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.35.1, Firefox ESR 140.10.1 and Firefox 150.0.1. 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
Tracker1806249
Fix commit8274f57990a4 (firefox) +12/-11
CISA KEVNot listed
CreditedAndrew McCreight, Christian Holler, Lee Salzman, Maurice Dauer, Tom Schuster, Wayne Mery and the Mozilla Fuzzing Team
Disclosed2026-05-07

Changed Functions

FunctionChangeNotes
if
gfx/layers/wr/WebRenderLayerManager.cpp
modified

Files Changed

  • gfx/layers/ipc/CompositorBridgeParent.cpp
  • gfx/layers/ipc/ContentCompositorBridgeParent.cpp
  • gfx/layers/ipc/PWebRenderBridge.ipdl
  • gfx/layers/wr/WebRenderBridgeParent.h
  • gfx/layers/wr/WebRenderLayerManager.cpp
diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp
index 23639683019..25fadf921fe 100644
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1119,8 +1119,7 @@ PWebRenderBridgeParent* CompositorBridgeParent::AllocPWebRenderBridgeParent(
       });
 
   mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, mVsyncRate);
-  mWrBridge.get()->AddRef();  // IPDL reference
-  {                           // scope lock
+  {  // scope lock
     StaticMonitorAutoLock lock(sIndirectLayerTreesLock);
     MOZ_ASSERT(sIndirectLayerTrees[mRootLayerTreeID].mWrBridge == nullptr);
     sIndirectLayerTrees[mRootLayerTreeID].mWrBridge = mWrBridge;
@@ -1139,7 +1138,6 @@ bool CompositorBridgeParent::DeallocPWebRenderBridgeParent(
       it->second.mWebRenderAPI = nullptr;
     }
   }
-  parent->Release();  // IPDL reference
   return true;
 }
 
diff --git a/gfx/layers/ipc/ContentCompositorBridgeParent.cpp b/gfx/layers/ipc/ContentCompositorBridgeParent.cpp
index 3a44a73fbfd..24085930889 100644
--- a/gfx/layers/ipc/ContentCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/ContentCompositorBridgeParent.cpp
@@ -177,7 +177,6 @@ ContentCompositorBridgeParent::AllocPWebRenderBridgeParent(
     nsCString error("NO_PARENT");
     WebRenderBridgeParent* parent =
         WebRenderBridgeParent::CreateDestroyed(aPipelineId, std::move(error));
-    parent->AddRef();  // IPDL reference
     return parent;
   }
 
@@ -186,7 +185,6 @@ ContentCompositorBridgeParent::AllocPWebRenderBridgeParent(
   WebRenderBridgeParent* parent = new WebRenderBridgeParent(
       this, aPipelineId, root->CompositorScheduler(), std::move(api),
       std::move(holder), cbp->GetVsyncInterval());
-  parent->AddRef();  // IPDL reference
 
   {  // scope lock
     StaticMonitorAutoLock lock(CompositorBridgeParent::sIndirectLayerTreesLock);
@@ -202,7 +200,6 @@ bool ContentCompositorBridgeParent::DeallocPWebRenderBridgeParent(
     PWebRenderBridgeParent* aActor) {
   WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
   EraseLayerState(wr::AsLayersId(parent->PipelineId()));
-  parent->Release();  // IPDL reference
   return true;
 }
 
diff --git a/gfx/layers/ipc/PWebRenderBridge.ipdl b/gfx/layers/ipc/PWebRenderBridge.ipdl
index f22b5d0aa0e..aa24586a5c7 100644
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -32,7 +32,7 @@ using mozilla::VsyncId from "mozilla/VsyncDispatcher.h";
 namespace mozilla {
 namespace layers {
 
-[ManualDealloc, ParentImpl=virtual]
+[ParentImpl=virtual]
 sync protocol PWebRenderBridge
 {
   manager PCompositorBridge;
diff --git a/gfx/layers/wr/WebRenderBridgeParent.h b/gfx/layers/wr/WebRenderBridgeParent.h
index 782fef2fd77..eccf2f87aac 100644
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -64,6 +64,9 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
                                     public CompositableParentManager,
                                     public FrameRecorder {
  public:
+  NS_INLINE_DECL_REFCOUNTING_INHERITED(WebRenderBridgeParent,
+                                       ISurfaceAllocator);
+
   // Constructor for root WebRenderBridgeParents.
   WebRenderBridgeParent(CompositorBridgeParent* aCompositorBridge,
                         const wr::PipelineId& aPipelineId,
diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp
index 0bc1c139baa..f349de77155 100644
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -79,9 +79,12 @@ RefPtr<WebRenderLayerManager> WebRenderLayerManager::Create(
                         << " isParent: " << XRE_IsParentProcess();
   }
 
-  PWebRenderBridgeChild* bridge =
-      aCBChild->SendPWebRenderBridgeConstructor(aPipelineId, size, windowKind);
-  if (!bridge) {
+  PWebRenderBridgeChild* wrBridge =
+      (static_cast<CompositorBridgeChild*>(aCBChild))
+          ->AllocPWebRenderBridgeChild(aPipelineId, size, windowKind);
+  PWebRenderBridgeChild* actor = aCBChild->SendPWebRenderBridgeConstructor(
+      wrBridge, aPipelineId, size, windowKind);
+  if (!actor) {
     // This should only fail if we attempt to access a layer we don't have
     // permission for, or more likely, the GPU process crashed again during
     // reinitialization. We can expect to be notified again to reinitialize
@@ -94,7 +97,7 @@ RefPtr<WebRenderLayerManager> WebRenderLayerManager::Create(
   }
 
   RefPtr<WebRenderBridgeChild> wrChild =
-      static_cast<WebRenderBridgeChild*>(bridge);
+      static_cast<WebRenderBridgeChild*>(actor);
   return new WebRenderLayerManager(aWidget, wrChild.forget());
 }
 
Loading diff…