Chrome · ANGLE
CVE-2026-79142
OOB in ANGLE
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
include/GLSLANG/ShaderLang.hinclude/platform/autogen/FeaturesGL_autogen.hinclude/platform/gl_features.jsonscripts/code_generation_hashes/ANGLE_shader_translator.jsonsrc/compiler.gnisrc/compiler/fuzz/translator_fuzzer.cppsrc/compiler/translator/Compiler.cppsrc/compiler/translator/ParseContext.cpp
Patch
From 922804e75179e45560959b935b5aebc895876fdf Mon Sep 17 00:00:00 2001 From: Shahbaz Youssefi <[email protected]> Date: Wed, 08 Jul 2026 17:19:31 -0400 Subject: [PATCH] Translator: Always declare named structs globally ... and separately. This is required for an upcoming AST transformation that references structs in helper functions, even if it's locally declared in the shader. At the same time, this change makes the RegenerateStructNames transformation obsolete and allows SeparateDeclarations to be simplified. Bug: chromium:529509587 Change-Id: I76d76b7fccb478e05eeb365a2b56ec85b4cd1e4c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/8065288 Reviewed-by: Geoff Lang <[email protected]> Commit-Queue: Shahbaz Youssefi <[email protected]> Reviewed-by: Kenneth Russell <[email protected]> --- diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h index 889423e..dd5bba9 100644 --- a/include/GLSLANG/ShaderLang.h +++ b/include/GLSLANG/ShaderLang.h @@ -26,7 +26,7 @@ // Version number for shader translation API. // It is incremented every time the API changes. -#define ANGLE_SH_VERSION 414 +#define ANGLE_SH_VERSION 415 enum ShShaderSpec { @@ -236,8 +236,7 @@ // Linux/Mac driver bugs. uint64_t scalarizeVecAndMatConstructorArgs : 1; - // This flag overwrites a struct name with a unique prefix. It is intended as a workaround for - // drivers that do not handle struct scopes correctly, including all Mac drivers and Linux AMD. + // This flag is a no-op and will be removed once chromium code no longer references it. uint64_t regenerateStructNames : 1; // This flag works around a bug in the HLSL compiler optimizer that folds certain constant pow diff --git a/include/platform/autogen/FeaturesGL_autogen.h b/include/platform/autogen/FeaturesGL_autogen.h index 6b43b42..f39bce2 100644 --- a/include/platform/autogen/FeaturesGL_autogen.h +++ b/include/platform/autogen/FeaturesGL_autogen.h @@ -308,12 +308,6 @@ &members, }; - FeatureInfo regenerateStructNames = { - "regenerateStructNames", - FeatureCategory::OpenGLWorkarounds, - &members, - }; - FeatureInfo readPixelsUsingImplementationColorReadFormatForNorm16 = { "readPixelsUsingImplementationColorReadFormatForNorm16", FeatureCategory::OpenGLWorkarounds, diff --git a/include/platform/gl_features.json b/include/platform/gl_features.json index 79e0837..f035663 100644 --- a/include/platform/gl_features.json +++ b/include/platform/gl_features.json @@ -387,15 +387,6 @@ "issue": "http://crbug.com/642605" }, { - "name": "regenerate_struct_names", - "category": "Workarounds", - "description": [ - "All Mac drivers do not handle struct scopes correctly. This workaround overwrites a struct", - "name with a unique prefix." - ], - "issue": "http://crbug.com/403957" - }, - { "name": "read_pixels_using_implementation_color_read_format_for_norm16", "category": "Workarounds", "description": [ diff --git a/scripts/code_generation_hashes/ANGLE_shader_translator.json b/scripts/code_generation_hashes/ANGLE_shader_translator.json index be7aefc..39548fa 100644 --- a/scripts/code_generation_hashes/ANGLE_shader_translator.json +++ b/scripts/code_generation_hashes/ANGLE_shader_translator.json @@ -6,11 +6,11 @@ "src/compiler/translator/glslang.l": "aa7542c5cad1b9476b76426958b58d61", "src/compiler/translator/glslang.y": - "06a935b7c9568df4de1de4cce95e668c", + "6c4f0838296500f96a99e2e0b0715529", "src/compiler/translator/glslang_lex_autogen.cpp": "93a9f8320f1ff165d2b31d9e8add91c3", "src/compiler/translator/glslang_tab_autogen.cpp": - "c9d45a90f418dc0f0d58a11a94951414", + "86d84b555871d272c2618e3c645c7dae", "src/compiler/translator/glslang_tab_autogen.h": "f1c4d0111ce0d8977503b38c9b7b23df", "tools/flex-bison/linux/bison.sha1": diff --git a/src/compiler.gni b/src/compiler.gni index 772269b..a7d5bbf 100644 --- a/src/compiler.gni +++ b/src/compiler.gni @@ -194,7 +194,6 @@ "src/compiler/translator/tree_ops/SplitSequenceOperator.cpp", "src/compiler/translator/tree_ops/SplitSequenceOperator.h", "src/compiler/translator/tree_ops/glsl/ExpandFragmentOutputsToVec4.h", - "src/compiler/translator/tree_ops/glsl/RegenerateStructNames.h", "src/compiler/translator/tree_ops/glsl/RewriteRepeatedAssignToSwizzled.h", "src/compiler/translator/tree_ops/glsl/UseInterfaceBlockFields.h", "src/compiler/translator/tree_ops/glsl/apple/AddAndTrueToLoopCondition.h", @@ -260,7 +259,6 @@ "src/compiler/translator/glsl/TranslatorGLSL.cpp", "src/compiler/translator/glsl/VersionGLSL.cpp", "src/compiler/translator/tree_ops/glsl/ExpandFragmentOutputsToVec4.cpp", - "src/compiler/translator/tree_ops/glsl/RegenerateStructNames.cpp", "src/compiler/translator/tree_ops/glsl/RewriteRepeatedAssignToSwizzled.cpp", "src/compiler/translator/tree_ops/glsl/UseInterfaceBlockFields.cpp", ] diff --git a/src/compiler/fuzz/translator_fuzzer.cpp b/src/compiler/fuzz/translator_fuzzer.cpp index 694bd6a..428fc56 100644 --- a/src/compiler/fuzz/translator_fuzzer.cpp +++ b/src/compiler/fuzz/translator_fuzzer.cpp @@ -100,10 +100,10 @@ if (!IsOutputGLSL(shaderOutput) && !IsOutputESSL(shaderOutput)) { - hasUnsupportedOptions = - hasUnsupportedOptions || options.emulateAtan2FloatFunction || options.clampFragDepth || - options.regenerateStructNames || options.rewriteRepeatedAssignToSwizzled || - options.useUnusedStandardSharedBlocks || options.selectViewInNvGLSLVertexShader; + hasUnsupportedOptions = hasUnsupportedOptions || options.emulateAtan2FloatFunction || + options.clampFragDepth || options.rewriteRepeatedAssignToSwizzled || + options.useUnusedStandardSharedBlocks || + options.selectViewInNvGLSLVertexShader; hasUnsupportedOptions = hasUnsupportedOptions || hasMacGLSLOptions; } diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp index eb1d646..5a6c5e8 100644 --- a/src/compiler/translator/Compiler.cpp +++ b/src/compiler/translator/Compiler.cpp @@ -44,7 +44,6 @@ #include "compiler/translator/tree_ops/SeparateDeclarations.h" #include "compiler/translator/tree_ops/SimplifyLoopConditions.h" #include "compiler/translator/tree_ops/SplitSequenceOperator.h" -#include "compiler/translator/tree_ops/glsl/RegenerateStructNames.h" #include "compiler/translator/tree_ops/glsl/RewriteRepeatedAssignToSwizzled.h" #include "compiler/translator/tree_ops/glsl/UseInterfaceBlockFields.h" #include "compiler/translator/tree_ops/glsl/apple/AddAndTrueToLoopCondition.h" @@ -908,14 +907,6 @@ } } - if (compileOptions.regenerateStructNames) - { - if (!RegenerateStructNames(this, root, &mSymbolTable)) - { - return false; - } - } - if (compileOptions.emulateGLDrawID && IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw)) { diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp index e9198ba..dff5a36 100644 --- a/src/compiler/translator/ParseContext.cpp +++ b/src/compiler/translator/ParseContext.cpp @@ -24,6 +24,7 @@ #include "common/utilities.h" #include "compiler/preprocessor/SourceLocation.h" #include "compiler/translator/Declarator.h" +#include "compiler/translator/ImmutableStringBuilder.h" #include "compiler/translator/ValidateGlobalInitializer.h" #include "compiler/translator/glslang.h" #include "compiler/translator/tree_util/BuiltIn.h" @@ -459,6 +460,44 @@ return 0; } } + +enum class StructureOriginalScope +{ + Global, + FunctionLocal, +}; + +TIntermDeclaration *RenameAndDeclareStruct(TSymbolTable *symbolTable, + TStructure *structure, + StructureOriginalScope scope) +{ + ASSERT(!structure->name().empty()); + + // We need +2 space for _0 if global, or +11 for "_uniqueId" if function-local. Using +11 + // always for simplicity. +1 for the NUL terminator. + // + // If appending ID and the name is too long, cut off the end of the name. The ID makes it + // unique. + constexpr uint32_t kAppendExtraChars = 1 + 11; // underscore + 32-bit number
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/src/tests/angle_unittests.gni b/src/tests/angle_unittests.gni
index 628f197..b17edfa 100644
--- a/src/tests/angle_unittests.gni
+++ b/src/tests/angle_unittests.gni
@@ -108,10 +108,8 @@
"compiler_tests/QualificationOrderESSL31_test.cpp",
"compiler_tests/QualificationOrder_test.cpp",
"compiler_tests/RecordConstantPrecision_test.cpp",
- "compiler_tests/RegenerateStructNames_test.cpp",
"compiler_tests/RemoveUnreferencedVariables_test.cpp",
"compiler_tests/SamplerMultisample_test.cpp",
- "compiler_tests/SeparateDeclarations_test.cpp",
"compiler_tests/ShCompile_test.cpp",
"compiler_tests/ShaderValidation_test.cpp",
"compiler_tests/ShaderVariable_test.cpp",
diff --git a/src/tests/compiler_tests/CollectVariables_test.cpp b/src/tests/compiler_tests/CollectVariables_test.cpp
index b8e879f..18600ad 100644
--- a/src/tests/compiler_tests/CollectVariables_test.cpp
+++ b/src/tests/compiler_tests/CollectVariables_test.cpp
@@ -872,7 +872,7 @@
EXPECT_FALSE(uniform.isArray());
EXPECT_EQ("u", uniform.name);
EXPECT_EQ("webgl_1", uniform.mappedName);
- EXPECT_EQ("sType", uniform.structOrBlockName);
+ EXPECT_EQ("sType_0", uniform.structOrBlockName);
EXPECT_TRUE(uniform.staticUse);
EXPECT_TRUE(uniform.active);
diff --git a/src/tests/compiler_tests/RegenerateStructNames_test.cpp b/src/tests/compiler_tests/RegenerateStructNames_test.cpp
deleted file mode 100644
index 8f873e7..0000000
--- a/src/tests/compiler_tests/RegenerateStructNames_test.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//
-// Copyright 2017 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// RegenerateStructNames_test.cpp:
-// Tests for regenerating struct names.
-//
-
-#include "GLSLANG/ShaderLang.h"
-#include "angle_gl.h"
-#include "gtest/gtest.h"
-#include "tests/test_utils/compiler_test.h"
-
-using namespace sh;
-
-class RegenerateStructNamesTest : public MatchOutputCodeTest
-{
- public:
- RegenerateStructNamesTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_ESSL_OUTPUT)
- {
- ShCompileOptions defaultCompileOptions = {};
- defaultCompileOptions.regenerateStructNames = true;
- setDefaultCompileOptions(defaultCompileOptions);
- }
-};
-
-// Test that a struct defined in a function scope is renamed. The global struct that's used as a
-// type of a uniform cannot be renamed.
-TEST_F(RegenerateStructNamesTest, GlobalStructAndLocalStructWithTheSameName)
-{
- const std::string &shaderString =
- R"(precision mediump float;
-
- struct myStruct
- {
- float foo;
- };
-
- uniform myStruct us;
-
- void main()
- {
- struct myStruct
- {
- vec2 bar;
- };
- myStruct scoped;
- scoped.bar = vec2(1.0, 2.0) * us.foo;
- gl_FragColor = vec4(scoped.bar, 0.0, 1.0);
- })";
- compile(shaderString);
- EXPECT_TRUE(foundInCode("struct _umyStruct"));
- EXPECT_TRUE(foundInCode("struct _u_webgl_struct_"));
-}
-
-// Test that a nameless struct is handled gracefully.
-TEST_F(RegenerateStructNamesTest, NamelessStruct)
-{
- const std::string &shaderString =
- R"(precision mediump float;
-
- uniform float u;
-
- void main()
- {
- struct
- {
- vec2 bar;
- } scoped;
- scoped.bar = vec2(1.0, 2.0) * u;
- gl_FragColor = vec4(scoped.bar, 0.0, 1.0);
- })";
- compile(shaderString);
- EXPECT_TRUE(foundInCode("struct"));
-}
diff --git a/src/tests/compiler_tests/SeparateDeclarations_test.cpp b/src/tests/compiler_tests/SeparateDeclarations_test.cpp
deleted file mode 100644
index 01fb3f6..0000000
--- a/src/tests/compiler_tests/SeparateDeclarations_test.cpp
+++ /dev/null
@@ -1,419 +0,0 @@
-//
-// Copyright 2024 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// SeparateDeclarations.cpp:
-// Tests that compound declarations are rewritten to type declarations and variable declarations.
-//
-
-#include "GLSLANG/ShaderLang.h"
-#include "angle_gl.h"
-#include "gtest/gtest.h"
-#include "tests/test_utils/compiler_test.h"
-
-using namespace sh;
-
-namespace
-{
-
-class SeparateDeclarations : public MatchOutputCodeTest
-{
- public:
- SeparateDeclarations() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_ESSL_OUTPUT)
- {
- ShCompileOptions defaultCompileOptions = {};
- defaultCompileOptions.validateAST = true;
- setDefaultCompileOptions(defaultCompileOptions);
- }
-};
-
-class SeparateCompoundStructDeclarations : public MatchOutputCodeTest
-{
- public:
- SeparateCompoundStructDeclarations() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_ESSL_OUTPUT)
- {
- ShCompileOptions defaultCompileOptions = {};
- defaultCompileOptions.validateAST = true;
- defaultCompileOptions.separateCompoundStructDeclarations = true;
- setDefaultCompileOptions(defaultCompileOptions);
- }
-};
-
-class SeparateStructFunctionDeclarations : public MatchOutputCodeTest
-{
- public:
- SeparateStructFunctionDeclarations() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_ESSL_OUTPUT)
- {
- ShCompileOptions defaultCompileOptions = {};
- defaultCompileOptions.validateAST = true;
- setDefaultCompileOptions(defaultCompileOptions);
- }
-};
-
-TEST_F(SeparateDeclarations, Arrays)
-{
- const char kShader[] = R"(#version 300 es
-precision highp float;
-int a[1] = int[1](1), b[1] = int[1](2);
-out vec4 o;
-void main() {
- if (a[0] == b[0])
- o = vec4(1);
-})";
- const char kExpected[] = R"(#version 300 es
-const mediump int sbbd = 1;
-mediump int _ua[1] = int[1](sbbd);
-const mediump int sbbe = 2;
-mediump int _ub[1] = int[1](sbbe);
-out highp vec4 _uo;
-void main(){
- if ((_ua[0] == _ub[0]))
- {
- (_uo = vec4(1.0, 1.0, 1.0, 1.0));
- }
-}
-)";
- compile(kShader);
- EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
-}
-
-TEST_F(SeparateDeclarations, StructNoChange)
-{
- const char kShader[] = R"(#version 300 es
-precision highp float;
-struct S { vec3 d; } a;
-out vec4 o;
-void main() {
- if (a.d == vec3(2))
- o = vec4(1);
-})";
- const char kExpected[] = R"(#version 300 es
-struct _uS {
- highp vec3 _ud;
-} _ua;
-out highp vec4 _uo;
-void main(){
- if ((_ua._ud == vec3(2.0, 2.0, 2.0)))
- {
- (_uo = vec4(1.0, 1.0, 1.0, 1.0));
- }
-}
-)";
- compile(kShader);
- EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
-}
-
-TEST_F(SeparateDeclarations, Structs)
-{
- const char kShader[] = R"(#version 300 es
-precision highp float;
-struct S { vec3 d; } a, b;
-out vec4 o;
-void main() {
- if (a.d == b.d)
- o = vec4(1);
-})";
- const char kExpected[] = R"(#version 300 es
-struct _uS {
- highp vec3 _ud;
-} _ua;
-_uS _ub;
-out highp vec4 _uo;
-void main(){
- if ((_ua._ud == _ub._ud))
- {
- (_uo = vec4(1.0, 1.0, 1.0, 1.0));
- }
-}
-)";
- compile(kShader);
- EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
-}
-
-TEST_F(SeparateDeclarations, AnonymousStructNoChange)
-{
- const char kShader[] = R"(#version 300 es
-precision highp float;
-struct { vec3 d; } a;
-out vec4 o;
-void main() {
- if (any(lessThan(a.d, vec3(2))))
- o = vec4(1);
-})";
- const char kExpected[] = R"(#version 300 es
-struct {
- highp vec3 _ud;
-} _ua;
-out highp vec4 _uo;
-void main(){
- if (any(lessThan(_ua._ud, vec3(2.0, 2.0, 2.0))))
- {
- (_uo = vec4(1.0, 1.0, 1.0, 1.0));
- }
-}
-)";
- compile(kShader);
- EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
-}
-
-TEST_F(SeparateDeclarations, AnonymousStructs)
-{
- const char kShader[] = R"(#version 300 es
-precision highp float;
-struct { vec3 d; } a, b;
-out vec4 o;
-void main() {
- if (any(lessThan(a.d, b.d)))
- o = vec4(1);
-})";
- const char kExpected[] = R"(#version 300 es
-struct {
- highp vec3 _ud;
-} _ua;
-struct {
- highp vec3 _ud;
-} _ub;
-out highp vec4 _uo;
-void main(){
- if (any(lessThan(_ua._ud, _ub._ud)))
- {
- (_uo = vec4(1.0, 1.0, 1.0, 1.0));
- }
-}
-)";
- compile(kShader);
... (truncated)
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page