summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2017-09-17 18:25:39 +0200
committerNicolai Hähnle <[email protected]>2017-09-20 15:35:57 +0200
commit15cae12804ef288c7fb4cb9a38f7e32e6d8c4dc1 (patch)
treea16cb7a6c9e2aae62af08521e64143752e3941a7
parent62a8ca22cde9907726f63d6a1915390fb2f21cfe (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.cpp17
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;
}