High firefox Memory Corruption 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionMemory safety bugs present in Firefox ESR 115.36, Firefox ESR 140.11, Thunderbird ESR 140.11, Firefox 151 and Thunderbird 151. Some of these bugs showed evidence of memory corruption and we presume that with enough effort some of these could have been exploited to run arbitrary code.
ComponentGraphics
Bug ClassMemory Corruption
Tracker2029402
Fix commit30c9b7c8ee95 (firefox) +28/-0
CISA KEVNot listed
CreditedAndrew McCreight, Randell Jesup, Tom Ritter and the Mozilla Fuzzing Team
Disclosed2026-06-16

Changed Functions

FunctionChangeNotes
GLFragColorBroadcastTraverser
gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
modified

Files Changed

  • gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
index 25e1fde29a2..606a94ff9b9 100644
--- a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
@@ -26,6 +26,7 @@ namespace
 {
 
 constexpr const ImmutableString kGlFragDataString("gl_FragData");
+constexpr const ImmutableString kGlSecondaryFragDataString("gl_SecondaryFragDataEXT");
 
 class GLFragColorBroadcastTraverser : public TIntermTraverser
 {
@@ -42,6 +43,8 @@ class GLFragColorBroadcastTraverser : public TIntermTraverser
     bool isGLFragColorUsed() const { return mGLFragColorUsed; }
 
   protected:
+    bool visitGlobalQualifierDeclaration(Visit visit,
+                                         TIntermGlobalQualifierDeclaration *node) override;
     void visitSymbol(TIntermSymbol *node) override;
 
     TIntermBinary *constructGLFragDataNode(int index) const;
@@ -71,6 +74,31 @@ TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int
     return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero);
 }
 
+bool GLFragColorBroadcastTraverser::visitGlobalQualifierDeclaration(
+    Visit visit,
+    TIntermGlobalQualifierDeclaration *node)
+{
+    TIntermSymbol *symbol = node->getSymbol();
+    if (symbol->variable().symbolType() == SymbolType::BuiltIn)
+    {
+        if (symbol->getName() == "gl_FragColor")
+        {
+            queueReplacementWithParent(
+                node, node->getSymbol(),
+                ReferenceBuiltInVariable(kGlFragDataString, *mSymbolTable, mShaderVersion),
+                OriginalNode::IS_DROPPED);
+        }
+        else if (symbol->getName() == "gl_SecondaryFragColorEXT")
+        {
+            queueReplacementWithParent(
+                node, node->getSymbol(),
+                ReferenceBuiltInVariable(kGlSecondaryFragDataString, *mSymbolTable, mShaderVersion),
+                OriginalNode::IS_DROPPED);
+        }
+    }
+    return false;
+}
+
 void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node)
 {
     if (node->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_FragColor")
Loading diff…