[Mesa-dev] [PATCH 08/17] glsl: Avoid buffer overflow when assigning attribute locations

Samuel Iglesias Gonsalvez siglesias at igalia.com
Wed Jul 29 07:01:25 PDT 2015


From: Iago Toral Quiroga <itoral at igalia.com>

Shaders with excessive number of attributes (>16) can produce a crash
due to buffer overflow in assign_attribute_or_color_locations. The
overflow can happen because we declare a fixed size array that can hold
up to 16 attributes and we don't check that we don't go beyond that
limit.

This patch changes the limit from a fixed size of 16 element to
MAX2(MAX_VERTEX_GENERIC_ATTRIBS, MAX_DRAW_BUFFERS), which seems more
reasonable. It also makes sure that we don't process more than this
amount of attributes, producing a linker error if the shader requires
more than this.

v2:
  - With fragment shaders, this function processes outputs, not inputs (Ian)
  - Error message should tell if the problem is with vertex inputs or
    fragment outputs (Ian)
  - The function receives a parameter with the attribute limit (max_index),
    so no need to compute it inside
  - Assert if max_index is too large for the size of to_assign[]

Avoids crashes in 108 dEQP tests in these categories:
dEQP-GLES3.functional.transform_feedback.array_element.separate.
dEQP-GLES3.functional.transform_feedback.array_element.interleaved.*
---
 src/glsl/linker.cpp | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index a781211..12b7780 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -2386,7 +2386,9 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
 	 /* Reversed because we want a descending order sort below. */
 	 return r->slots - l->slots;
       }
-   } to_assign[16];
+   } to_assign[MAX2(MAX_VERTEX_GENERIC_ATTRIBS, MAX_DRAW_BUFFERS)];
+
+   assert(max_index <= MAX2(MAX_VERTEX_GENERIC_ATTRIBS, MAX_DRAW_BUFFERS));
 
    unsigned num_attr = 0;
    unsigned total_attribs_size = 0;
@@ -2599,6 +2601,15 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
 	 continue;
       }
 
+      if (num_attr >= max_index) {
+         linker_error(prog,
+                      "Number of required %s exceeds allowed limit (limit=%d)",
+                      target_index == MESA_SHADER_VERTEX ?
+                        "vertex inputs" : "fragment outputs",
+                      max_index);
+         return false;
+      }
+
       to_assign[num_attr].slots = slots;
       to_assign[num_attr].var = var;
       num_attr++;
-- 
2.4.3



More information about the mesa-dev mailing list