glsl: fix several use-after-free bugs
The get_variable_being_redeclared() function can free the 'var' argument.
Thereafter, we cannot assume that 'var' is a valid pointer. This patch
replaces 'var->name' with 'earlier->name' in two places and calls
is_gl_identifier(var->name) before 'var' might get freed.
This fixes several piglit GLSL crashes, including:
spec/glsl-1.50/execution/geometry/clip-distance-in-param
spec/glsl-1.50/execution/geometry/clip-distance-bulk-copy
spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-before-global-redeclaration.geom
I'm not sure why these were not spotted sooner.
A similar bug was previously fixed by f9cecca7a
.
Cc: <mesa-stable@lists.freedesktop.org>
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
This commit is contained in:
parent
953a0af8e3
commit
14379a0644
|
@ -3767,7 +3767,7 @@ ast_declarator_list::hir(exec_list *instructions,
|
|||
earlier->data.how_declared == ir_var_declared_in_block) {
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"`%s' has already been redeclared using "
|
||||
"gl_PerVertex", var->name);
|
||||
"gl_PerVertex", earlier->name);
|
||||
}
|
||||
earlier->data.how_declared = ir_var_declared_normally;
|
||||
}
|
||||
|
@ -5706,17 +5706,21 @@ ast_interface_block::hir(exec_list *instructions,
|
|||
|
||||
var->data.stream = this->layout.stream;
|
||||
|
||||
/* Examine var name here since var may get deleted in the next call */
|
||||
bool var_is_gl_id = is_gl_identifier(var->name);
|
||||
|
||||
if (redeclaring_per_vertex) {
|
||||
ir_variable *earlier =
|
||||
get_variable_being_redeclared(var, loc, state,
|
||||
true /* allow_all_redeclarations */);
|
||||
if (!is_gl_identifier(var->name) || earlier == NULL) {
|
||||
if (!var_is_gl_id || earlier == NULL) {
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"redeclaration of gl_PerVertex can only "
|
||||
"include built-in variables");
|
||||
} else if (earlier->data.how_declared == ir_var_declared_normally) {
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"`%s' has already been redeclared", var->name);
|
||||
"`%s' has already been redeclared",
|
||||
earlier->name);
|
||||
} else {
|
||||
earlier->data.how_declared = ir_var_declared_in_block;
|
||||
earlier->reinit_interface_type(block_type);
|
||||
|
|
Loading…
Reference in New Issue