High firefox Memory Corruption 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionMemory safety bugs present in Firefox ESR 140.9, Thunderbird ESR 140.9, Firefox 149 and Thunderbird 149. 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
Tracker2010727
Fix commitfc14fc2a0086 (firefox) +29/-16
CISA KEVNot listed
CreditedAlex Franchuk, Andrew McCreight, Brian Grinstead, Christian Holler, Jan de Mooij, Maurice Dauer, Sebastian Hengst, Tom Schuster and the Mozilla Fuzzing Team
Disclosed2026-04-21

Changed Functions

FunctionChangeNotes
if
gfx/layers/ipc/VideoBridgeParent.cpp
modified

Files Changed

  • gfx/layers/ipc/VideoBridgeParent.cpp
  • gfx/layers/ipc/VideoBridgeParent.h
diff --git a/gfx/layers/ipc/VideoBridgeParent.cpp b/gfx/layers/ipc/VideoBridgeParent.cpp
index d7c957acbf2..3ef885d3137 100644
--- a/gfx/layers/ipc/VideoBridgeParent.cpp
+++ b/gfx/layers/ipc/VideoBridgeParent.cpp
@@ -99,16 +99,16 @@ already_AddRefed<TextureHost> VideoBridgeParent::LookupTextureAsync(
 
   MOZ_ASSERT(mCompositorThreadHolder->IsInThread());
 
-  auto* actor = mTextureMap[aSerial];
-  if (NS_WARN_IF(!actor)) {
+  const auto i = mTextureMap.find(aSerial);
+  if (NS_WARN_IF(i == mTextureMap.end())) {
     return nullptr;
   }
 
-  if (NS_WARN_IF(aContentId != TextureHost::GetTextureContentId(actor))) {
+  if (NS_WARN_IF(aContentId != i->second.mContentId)) {
     return nullptr;
   }
 
-  return do_AddRef(TextureHost::AsTextureHost(actor));
+  return do_AddRef(i->second.mTextureHost);
 }
 
 already_AddRefed<TextureHost> VideoBridgeParent::LookupTexture(
@@ -120,12 +120,12 @@ already_AddRefed<TextureHost> VideoBridgeParent::LookupTexture(
     return nullptr;
   }
 
-  auto* actor = mTextureMap[aSerial];
-  if (actor) {
-    if (NS_WARN_IF(aContentId != TextureHost::GetTextureContentId(actor))) {
+  auto i = mTextureMap.find(aSerial);
+  if (i != mTextureMap.end()) {
+    if (NS_WARN_IF(aContentId != i->second.mContentId)) {
       return nullptr;
     }
-    return do_AddRef(TextureHost::AsTextureHost(actor));
+    return do_AddRef(i->second.mTextureHost);
   }
 
   // We cannot block on the Compositor thread because that is the thread we get
@@ -166,16 +166,16 @@ already_AddRefed<TextureHost> VideoBridgeParent::LookupTexture(
     lock.Wait();
   }
 
-  actor = mTextureMap[aSerial];
-  if (!actor) {
+  i = mTextureMap.find(aSerial);
+  if (NS_WARN_IF(i == mTextureMap.end())) {
     return nullptr;
   }
 
-  if (NS_WARN_IF(aContentId != TextureHost::GetTextureContentId(actor))) {
+  if (NS_WARN_IF(aContentId != i->second.mContentId)) {
     return nullptr;
   }
 
-  return do_AddRef(TextureHost::AsTextureHost(actor));
+  return do_AddRef(i->second.mTextureHost);
 }
 
 void VideoBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
@@ -259,13 +259,21 @@ PTextureParent* VideoBridgeParent::AllocPTextureParent(
   }
 
   MonitorAutoLock lock(mMonitor);
-  mTextureMap[aSerial] = parent;
+  mTextureMap.insert(
+      {aSerial, {TextureHost::AsTextureHost(parent), aContentId}});
   return parent;
 }
 
 bool VideoBridgeParent::DeallocPTextureParent(PTextureParent* actor) {
-  MonitorAutoLock lock(mMonitor);
-  mTextureMap.erase(TextureHost::GetTextureSerial(actor));
+  RefPtr<TextureHost> textureHost;
+  {
+    MonitorAutoLock lock(mMonitor);
+    auto i = mTextureMap.find(TextureHost::GetTextureSerial(actor));
+    if (i != mTextureMap.end()) {
+      textureHost = std::move(i->second.mTextureHost);
+      mTextureMap.erase(i);
+    }
+  }
   return TextureHost::DestroyIPDLActor(actor);
 }
 
diff --git a/gfx/layers/ipc/VideoBridgeParent.h b/gfx/layers/ipc/VideoBridgeParent.h
index 1443afa695a..7a23a29392a 100644
--- a/gfx/layers/ipc/VideoBridgeParent.h
+++ b/gfx/layers/ipc/VideoBridgeParent.h
@@ -71,10 +71,15 @@ class VideoBridgeParent final : public PVideoBridgeParent,
 
   void DoUnregisterExternalImages();
 
+  struct TextureHolder {
+    RefPtr<TextureHost> mTextureHost;
+    dom::ContentParentId mContentId;
+  };
+
   Monitor mMonitor;
   RefPtr<CompositorThreadHolder> mCompositorThreadHolder
       MOZ_GUARDED_BY(mMonitor);
-  std::map<uint64_t, PTextureParent*> mTextureMap MOZ_GUARDED_BY(mMonitor);
+  std::map<uint64_t, TextureHolder> mTextureMap MOZ_GUARDED_BY(mMonitor);
   bool mClosed;
 };
 
Loading diff…