diff options
author | Nicolai Hähnle <[email protected]> | 2017-09-17 18:25:39 +0200 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2017-09-20 15:35:57 +0200 |
commit | 15cae12804ef288c7fb4cb9a38f7e32e6d8c4dc1 (patch) | |
tree | a16cb7a6c9e2aae62af08521e64143752e3941a7 | |
parent | 62a8ca22cde9907726f63d6a1915390fb2f21cfe (diff) |
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: [email protected]
Reviewed-by: Timothy Arceri <[email protected]>
-rw-r--r-- | src/compiler/glsl/linker.cpp | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 141bf430370..422b8ecd13e 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -2651,12 +2651,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(); @@ -2882,6 +2884,12 @@ assign_attribute_or_color_locations(void *mem_ctx, } } } + + /* At most one variable per fragment output component should + * reach this. */ + assert(assigned_attr < ARRAY_SIZE(assigned)); + assigned[assigned_attr] = var; + assigned_attr++; } else if (target_index == MESA_SHADER_FRAGMENT || (prog->IsES && prog->data->Version >= 300)) { linker_error(prog, "overlapping location is assigned " @@ -2921,9 +2929,6 @@ assign_attribute_or_color_locations(void *mem_ctx, double_storage_locations |= (use_mask << attr); } - assigned[assigned_attr] = var; - assigned_attr++; - continue; } |