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.7, Thunderbird ESR 140.7, Firefox 147 and Thunderbird 147. 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.
ComponentCore
Bug ClassMemory Corruption
Tracker2008912
Fix commit690933d7cd71 (firefox) +50/-0
CISA KEVNot listed
CreditedAndrew McCreight, Maurice Dauer, Olli Pettay, Ryan Hunt
Disclosed2026-02-24

Changed Functions

FunctionChangeNotes
if
docshell/base/BrowsingContext.cpp
modified
if
docshell/base/WindowContext.cpp
modified

Files Changed

  • docshell/base/BrowsingContext.cpp
  • docshell/base/BrowsingContextGroup.cpp
  • docshell/base/BrowsingContextGroup.h
  • docshell/base/WindowContext.cpp
diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp
index 0f831327017..8f2d0cd8ce1 100644
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
@@ -4590,6 +4590,10 @@ bool ParamTraits<MaybeDiscarded<BrowsingContext>>::Read(
   if (id == 0) {
     *aResult = nullptr;
   } else if (RefPtr<BrowsingContext> bc = BrowsingContext::Get(id)) {
+    if (!bc->Group()->IsKnownForMessageReader(aReader)) {
+      return false;
+    }
+
     *aResult = std::move(bc);
   } else {
     aResult->SetDiscarded(id);
diff --git a/docshell/base/BrowsingContextGroup.cpp b/docshell/base/BrowsingContextGroup.cpp
index 3910c5a54cc..753b6c18a45 100644
--- a/docshell/base/BrowsingContextGroup.cpp
+++ b/docshell/base/BrowsingContextGroup.cpp
@@ -251,6 +251,42 @@ ContentParent* BrowsingContextGroup::GetHostProcess(
   return mHosts.GetWeak(aRemoteType);
 }
 
+bool BrowsingContextGroup::IsKnownForMessageReader(
+    IPC::MessageReader* aReader) {
+  if (!aReader->GetActor()) {
+    aReader->FatalError(
+        "No actor for BrowsingContextGroup::IsKnownForMessageReader");
+    return false;
+  }
+
+  mozilla::ipc::IToplevelProtocol* topActor =
+      aReader->GetActor()->ToplevelProtocol();
+  switch (topActor->GetProtocolId()) {
+    case PInProcessMsgStart:
+      // PInProcess always exists only within a single process, so we don't need
+      // to do any validation on it.
+      return true;
+
+    case PContentMsgStart:
+      // The process should only be able to name this BCG if it is
+      // subscribed, or if the BCG has been destroyed (and has therefore
+      // stopped tracking subscribers).
+      if (topActor->GetSide() == mozilla::ipc::ParentSide && !mDestroyed &&
+          !mSubscribers.Contains(static_cast<ContentParent*>(topActor))) {
+        aReader->FatalError(
+            "Process is not subscribed to this BrowsingContextGroup");
+        return false;
+      }
+      return true;
+
+    default:
+      aReader->FatalError(
+          "Unsupported toplevel actor for "
+          "BrowsingContextGroup::IsKnownForMessageReader");
+      return false;
+  }
+}
+
 void BrowsingContextGroup::UpdateToplevelsSuspendedIfNeeded() {
   if (!StaticPrefs::dom_suspend_inactive_enabled()) {
     return;
diff --git a/docshell/base/BrowsingContextGroup.h b/docshell/base/BrowsingContextGroup.h
index 835402ca971..188ca03cae7 100644
--- a/docshell/base/BrowsingContextGroup.h
+++ b/docshell/base/BrowsingContextGroup.h
@@ -86,6 +86,12 @@ class BrowsingContextGroup final : public nsWrapperCache {
   // BrowsingContextGroup, if possible.
   ContentParent* GetHostProcess(const nsACString& aRemoteType);
 
+  // Check if the process which sent the message being read from aReader is
+  // aware of this BrowsingContextGroup's existence.
+  // If this returns false, it will first set a fatal error on aReader with more
+  // details.
+  bool IsKnownForMessageReader(IPC::MessageReader* aReader);
+
   // When a BrowsingContext is being discarded, we may want to keep the
   // corresponding BrowsingContextGroup alive until the other process
   // acknowledges that the BrowsingContext has been discarded. A `KeepAlive`
diff --git a/docshell/base/WindowContext.cpp b/docshell/base/WindowContext.cpp
index aa7cd8fb46f..6493b7f1362 100644
--- a/docshell/base/WindowContext.cpp
+++ b/docshell/base/WindowContext.cpp
@@ -846,6 +846,10 @@ bool ParamTraits<MaybeDiscarded<WindowContext>>::Read(
   if (id == 0) {
     *aResult = nullptr;
   } else if (RefPtr<WindowContext> wc = WindowContext::GetById(id)) {
+    if (!wc->Group()->IsKnownForMessageReader(aReader)) {
+      return false;
+    }
+
     *aResult = std::move(wc);
   } else {
     aResult->SetDiscarded(id);
Loading diff…