From: Dave Airlie <airlied@gmail.com>
Date: Thu May 30 20:21:56 2013 +1000
Subject: [PATCH]i965: fix problem with constant out of bounds access (v3)
Patch-Mainline: Upstream/0677ea063cd96adefe87c1fb01ef7c66d905535b
Git-commit: 271c39849f68d05c008318787ba40e7a4d1ba776
Git-repo: git://anongit.freedesktop.org/git/mesa/mesa
References: bnc #828007
Signed-off-by: Egbert Eich <eich@suse.com>

Okay I now understand why Frank would want to run away, this is
my attempt at fixing the CVE out of bounds access to constants
outside the range. This attempt converts any illegal constants
to constant 0 as per the GL spec, and is undefined behaviour.

A future patch should add some debug for users to find this out,
but this needs to be backported to stable branches.

CVE-2013-1872

v2: drop the last hunk which was a separate fix (now in master).
hopefully fix the indentations.

v3: don't fail piglit, the whole 8/16 dispatch stuff was over
my head, and I spent a while figuring it out, but this one is
definitely safe, one piglit pass extra on my Ironlake.

NOTE: This is a candidate for stable branches.

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.cpp         | 15 ++++++++++++++-
 Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.h           |  1 +
 Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp |  3 +++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.cpp b/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.cpp
index 167ea08..b541f30 100644
--- a/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -496,6 +496,7 @@ fs_visitor::import_uniforms(fs_visitor *v)
 			   import_uniforms_callback,
 			   variable_ht);
    this->params_remap = v->params_remap;
+   this->nr_params_remap = v->nr_params_remap;
 }
 
 /* Our support for uniforms is piggy-backed on the struct
@@ -1110,6 +1111,7 @@ fs_visitor::remove_dead_constants()
 {
    if (c->dispatch_width == 8) {
       this->params_remap = ralloc_array(mem_ctx, int, c->prog_data.nr_params);
+      this->nr_params_remap = c->prog_data.nr_params;
 
       for (unsigned int i = 0; i < c->prog_data.nr_params; i++)
 	 this->params_remap[i] = -1;
@@ -1124,7 +1126,14 @@ fs_visitor::remove_dead_constants()
 	    if (inst->src[i].file != UNIFORM)
 	       continue;
 
-	    assert(constant_nr < (int)c->prog_data.nr_params);
+	    /* Section 5.11 of the OpenGL 4.3 spec says:
+	     *
+	     *     "Out-of-bounds reads return undefined values, which include
+	     *     values from other variables of the active program or zero."
+	     */
+	    if (constant_nr < 0 || constant_nr >= (int)c->prog_data.nr_params) {
+	       constant_nr = 0;
+	    }
 
 	    /* For now, set this to non-negative.  We'll give it the
 	     * actual new number in a moment, in order to keep the
@@ -1175,6 +1184,10 @@ fs_visitor::remove_dead_constants()
 	 if (inst->src[i].file != UNIFORM)
 	    continue;
 
+	 /* as above alias to 0 */
+	 if (constant_nr < 0 || constant_nr >= (int)this->nr_params_remap) {
+	    constant_nr = 0;
+	 }
 	 assert(this->params_remap[constant_nr] != -1);
 	 inst->src[i].reg = this->params_remap[constant_nr];
 	 inst->src[i].reg_offset = 0;
diff --git a/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.h b/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.h
index e69de31..2a9cc60 100644
--- a/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs.h
@@ -368,6 +368,7 @@ public:
     * uniform index.
     */
    int *params_remap;
+   int nr_params_remap;
 
    struct hash_table *variable_ht;
    ir_variable *frag_depth;
diff --git a/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index eabc121..d8c420a 100644
--- a/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/Mesa-9.0.3/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -2279,6 +2279,9 @@ fs_visitor::fs_visitor(struct brw_wm_compile *c, struct gl_shader_program *prog,
    this->virtual_grf_use = NULL;
    this->live_intervals_valid = false;
 
+   this->params_remap = NULL;
+   this->nr_params_remap = 0;
+
    this->force_uncompressed_stack = 0;
    this->force_sechalf_stack = 0;
 }
