[Mesa-dev] [PATCH 3/3] glsl: avoid accessing invalid memory after get_variable_being_redeclared()
Nicolai Hähnle
nhaehnle at gmail.com
Wed Sep 13 15:49:28 UTC 2017
Nice improvement, I remember being bitten by this in the past!
Series is:
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
On 13.09.2017 12:46, Iago Toral Quiroga wrote:
> After get_variable_being_redeclared() has been called, it is no longer
> safe to access the original variable pointer, since its memory might have
> been freed. Aavoid potential bugs by re-assigning the original variable
> pointer to the result of the function call, making it impossible for the
> remaining code to access an invalid variable pointer.
> ---
> src/compiler/glsl/ast_to_hir.cpp | 39 +++++++++++++++++++--------------------
> 1 file changed, 19 insertions(+), 20 deletions(-)
>
> diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
> index 5600e14c31..45c8ca2a5d 100644
> --- a/src/compiler/glsl/ast_to_hir.cpp
> +++ b/src/compiler/glsl/ast_to_hir.cpp
> @@ -5459,22 +5459,21 @@ ast_declarator_list::hir(exec_list *instructions,
> bool var_is_gl_id = is_gl_identifier(var->name);
>
> bool is_redeclaration;
> - ir_variable *declared_var =
> - get_variable_being_redeclared(&var, decl->get_location(), state,
> - false /* allow_all_redeclarations */,
> - &is_redeclaration);
> + var = get_variable_being_redeclared(&var, decl->get_location(), state,
> + false /* allow_all_redeclarations */,
> + &is_redeclaration);
> if (is_redeclaration) {
> if (var_is_gl_id &&
> - declared_var->data.how_declared == ir_var_declared_in_block) {
> + var->data.how_declared == ir_var_declared_in_block) {
> _mesa_glsl_error(&loc, state,
> "`%s' has already been redeclared using "
> - "gl_PerVertex", declared_var->name);
> + "gl_PerVertex", var->name);
> }
> - declared_var->data.how_declared = ir_var_declared_normally;
> + var->data.how_declared = ir_var_declared_normally;
> }
>
> if (decl->initializer != NULL) {
> - result = process_initializer(declared_var,
> + result = process_initializer(var,
> decl, this->type,
> &initializer_instructions, state);
> } else {
> @@ -5494,7 +5493,7 @@ ast_declarator_list::hir(exec_list *instructions,
> }
>
> if (state->es_shader) {
> - const glsl_type *const t = declared_var->type;
> + const glsl_type *const t = var->type;
>
> /* Skip the unsized array check for TCS/TES/GS inputs & TCS outputs.
> *
> @@ -5516,10 +5515,10 @@ ast_declarator_list::hir(exec_list *instructions,
> * present, as per the following table."
> */
> const bool implicitly_sized =
> - (declared_var->data.mode == ir_var_shader_in &&
> + (var->data.mode == ir_var_shader_in &&
> state->stage >= MESA_SHADER_TESS_CTRL &&
> state->stage <= MESA_SHADER_GEOMETRY) ||
> - (declared_var->data.mode == ir_var_shader_out &&
> + (var->data.mode == ir_var_shader_out &&
> state->stage == MESA_SHADER_TESS_CTRL);
>
> if (t->is_unsized_array() && !implicitly_sized)
> @@ -5550,8 +5549,8 @@ ast_declarator_list::hir(exec_list *instructions,
> * "It is a compile-time error to declare an unsized array of
> * atomic_uint"
> */
> - if (declared_var->type->is_unsized_array() &&
> - declared_var->type->without_array()->base_type == GLSL_TYPE_ATOMIC_UINT) {
> + if (var->type->is_unsized_array() &&
> + var->type->without_array()->base_type == GLSL_TYPE_ATOMIC_UINT) {
> _mesa_glsl_error(& loc, state,
> "Unsized array of atomic_uint is not allowed");
> }
> @@ -5575,7 +5574,7 @@ ast_declarator_list::hir(exec_list *instructions,
> * after the initializer if present or immediately after the name
> * being declared if not."
> */
> - if (!state->symbols->add_variable(declared_var)) {
> + if (!state->symbols->add_variable(var)) {
> YYLTYPE loc = this->get_location();
> _mesa_glsl_error(&loc, state, "name `%s' already taken in the "
> "current scope", decl->identifier);
> @@ -5588,7 +5587,7 @@ ast_declarator_list::hir(exec_list *instructions,
> * global var is decled, then the function is defined with usage of
> * the global var. See glslparsertest's CorrectModule.frag.
> */
> - instructions->push_head(declared_var);
> + instructions->push_head(var);
> }
>
> instructions->append_list(&initializer_instructions);
> @@ -8217,7 +8216,7 @@ ast_interface_block::hir(exec_list *instructions,
>
> if (redeclaring_per_vertex) {
> bool is_redeclaration;
> - ir_variable *declared_var =
> + var =
> get_variable_being_redeclared(&var, loc, state,
> true /* allow_all_redeclarations */,
> &is_redeclaration);
> @@ -8225,13 +8224,13 @@ ast_interface_block::hir(exec_list *instructions,
> _mesa_glsl_error(&loc, state,
> "redeclaration of gl_PerVertex can only "
> "include built-in variables");
> - } else if (declared_var->data.how_declared == ir_var_declared_normally) {
> + } else if (var->data.how_declared == ir_var_declared_normally) {
> _mesa_glsl_error(&loc, state,
> "`%s' has already been redeclared",
> - declared_var->name);
> + var->name);
> } else {
> - declared_var->data.how_declared = ir_var_declared_in_block;
> - declared_var->reinit_interface_type(block_type);
> + var->data.how_declared = ir_var_declared_in_block;
> + var->reinit_interface_type(block_type);
> }
> continue;
> }
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list