glsl: fix heap-use-after-free in ast_declarator_list::hir()
authorSamuel Iglesias Gonsálvez <siglesias@igalia.com>
Thu, 9 Feb 2017 12:54:46 +0000 (13:54 +0100)
committerSamuel Iglesias Gonsálvez <siglesias@igalia.com>
Thu, 23 Feb 2017 05:56:16 +0000 (06:56 +0100)
The get_variable_being_redeclared() function can free 'var' because
a re-declaration of an unsized array variable can establish the size, so
we set the array type to the 'earlier' declaration and free 'var' as it is
not needed anymore.

However, the same 'var' is referenced later in ast_declarator_list::hir().

This patch fixes it by picking the ir_variable_mode from the proper
ir_variable.

This error was detected by Address Sanitizer.

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Suggested-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99677
Cc: "17.0" <mesa-stable@lists.freedesktop.org>
Cc: "13.0" <mesa-stable@lists.freedesktop.org>
src/compiler/glsl/ast_to_hir.cpp

index b90ad97b1de4d3b59fdbc9740fc95082150305c5..344b2c7a62a722a6623476e89546366c3294cc73 100644 (file)
@@ -5259,11 +5259,13 @@ ast_declarator_list::hir(exec_list *instructions,
           *     sized by an earlier input primitive layout qualifier, when
           *     present, as per the following table."
           */
+         const enum ir_variable_mode mode = (const enum ir_variable_mode)
+            (earlier == NULL ? var->data.mode : earlier->data.mode);
          const bool implicitly_sized =
-            (var->data.mode == ir_var_shader_in &&
+            (mode == ir_var_shader_in &&
              state->stage >= MESA_SHADER_TESS_CTRL &&
              state->stage <= MESA_SHADER_GEOMETRY) ||
-            (var->data.mode == ir_var_shader_out &&
+            (mode == ir_var_shader_out &&
              state->stage == MESA_SHADER_TESS_CTRL);
 
          if (t->is_unsized_array() && !implicitly_sized)