From 46cfefc5be2006431a30484ff77992e5a691e6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= Date: Sun, 17 Sep 2017 18:25:39 +0200 Subject: [PATCH] glsl/linker: fix output variable overlap check Prevent an overflow caused by too many output variables. To limit the scope of the issue, write to the assigned array only for the non-ES fragment shader path, which is the only place where it's needed. Since the function will bail with an error when output variables with overlapping components are found, (max # of FS outputs) * 4 is an upper limit to the space we need. Found by address sanitizer. Fixes dEQP-GLES3.functional.attribute_location.bind_aliasing.* Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Timothy Arceri (cherry picked from commit 15cae12804ef288c7fb4cb9a38f7e32e6d8c4dc1) Squashed with commit: glsl/linker: properly fix output variable overlap check Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102904 Fixes: 15cae12804e ("glsl/linker: fix output variable overlap check") Reviewed-by: Kenneth Graunke (cherry picked from commit df8767a14e3eae4dcb8241b731b34e9379706795) Signed-off-by: Juan A. Suarez Romero --- src/compiler/glsl/linker.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 90c1084c50f..03b0db443c2 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -2661,12 +2661,14 @@ assign_attribute_or_color_locations(void *mem_ctx, } to_assign[32]; assert(max_index <= 32); - /* Temporary array for the set of attributes that have locations assigned. + /* Temporary array for the set of attributes that have locations assigned, + * for the purpose of checking overlapping slots/components of (non-ES) + * fragment shader outputs. */ - ir_variable *assigned[16]; + ir_variable *assigned[12 * 4]; /* (max # of FS outputs) * # components */ + unsigned assigned_attr = 0; unsigned num_attr = 0; - unsigned assigned_attr = 0; foreach_in_list(ir_instruction, node, sh->ir) { ir_variable *const var = node->as_variable(); @@ -2905,6 +2907,18 @@ assign_attribute_or_color_locations(void *mem_ctx, } } + if (target_index == MESA_SHADER_FRAGMENT && !prog->IsES) { + /* Only track assigned variables for non-ES fragment shaders + * to avoid overflowing the array. + * + * At most one variable per fragment output component should + * reach this. + */ + assert(assigned_attr < ARRAY_SIZE(assigned)); + assigned[assigned_attr] = var; + assigned_attr++; + } + used_locations |= (use_mask << attr); /* From the GL 4.5 core spec, section 11.1.1 (Vertex Attributes): @@ -2931,9 +2945,6 @@ assign_attribute_or_color_locations(void *mem_ctx, double_storage_locations |= (use_mask << attr); } - assigned[assigned_attr] = var; - assigned_attr++; - continue; }