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

Ian Romanick idr at freedesktop.org
Tue Jun 9 10:51:05 PDT 2015


On 03/11/2015 02:01 AM, Eduardo Lima Mitev wrote:
> 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_NV_FRAGMENT_PROGRAM_INPUTS), 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.
> 
> 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 | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index 0c44677..ffe8ede 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -1983,9 +1983,11 @@ 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_NV_FRAGMENT_PROGRAM_INPUTS)];

I believe Marek recently landed a patch that removes
MAX_NV_FRAGMENT_PROGRAM_INPUTS.  It's also not correct. :) This function
operates on vertex shader inputs or fragment shader outputs.

>     unsigned num_attr = 0;
> +   unsigned max_attr = (target_index == MESA_SHADER_VERTEX) ?
> +      MAX_VERTEX_GENERIC_ATTRIBS : MAX_NV_FRAGMENT_PROGRAM_INPUTS;

      const unsigned max_attr = ...

>  
>     foreach_in_list(ir_instruction, node, sh->ir) {
>        ir_variable *const var = node->as_variable();
> @@ -2147,6 +2149,13 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
>  	 continue;
>        }
>  
> +      if (num_attr >= max_attr) {
> +         linker_error(prog,
> +                      "Number of required attribute locations "
> +                      "exceeds allowed limit (limit=%d)", max_attr);

This message should be specialized for the stage (i.e., "vertex input"
vs. "fragment output").

> +         return false;
> +      }
> +
>        to_assign[num_attr].slots = slots;
>        to_assign[num_attr].var = var;
>        num_attr++;
> 



More information about the mesa-dev mailing list