Moderate firefox Logic Error 🔧 Commit mapped

Overview

Moderate
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionSandbox escape due to use-after-free in the DOM: Core & HTML component
ComponentDOM
Bug ClassLogic Error
Tracker2067973
Fix commita9439dc36d18 (firefox) +17/-2
CISA KEVNot listed
CreditedYaqoub Aldurayhim
Disclosed2026-09-29

Changed Functions

FunctionChangeNotes
if
dom/webbrowserpersist/WebBrowserPersistDocumentParent.cpp
modified

Files Changed

  • dom/webbrowserpersist/WebBrowserPersistDocumentParent.cpp
  • dom/webbrowserpersist/WebBrowserPersistDocumentParent.h
  • dom/webbrowserpersist/WebBrowserPersistResourcesParent.cpp
diff --git a/dom/webbrowserpersist/WebBrowserPersistDocumentParent.cpp b/dom/webbrowserpersist/WebBrowserPersistDocumentParent.cpp
index b70276ce9e4..7e4f3202124 100644
--- a/dom/webbrowserpersist/WebBrowserPersistDocumentParent.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistDocumentParent.cpp
@@ -54,6 +54,10 @@ WebBrowserPersistDocumentParent::~WebBrowserPersistDocumentParent() {
 mozilla::ipc::IPCResult WebBrowserPersistDocumentParent::RecvAttributes(
     Attrs&& aAttrs, NotNull<nsIPrincipal*> aPrincipal,
     nsIInputStream* aPostStream) {
+  if (!mOnReady || mReflection) {
+    return IPC_FAIL(this, "invalid actor state");
+  }
+
   auto* contentParent = dom::ContentParent::Cast(Manager());
   if (!contentParent->ValidatePrincipal(aPrincipal, {})) {
     return IPC_FAIL(this, "invalid principal");
diff --git a/dom/webbrowserpersist/WebBrowserPersistDocumentParent.h b/dom/webbrowserpersist/WebBrowserPersistDocumentParent.h
index 48807de7797..4388b7b4e90 100644
--- a/dom/webbrowserpersist/WebBrowserPersistDocumentParent.h
+++ b/dom/webbrowserpersist/WebBrowserPersistDocumentParent.h
@@ -40,6 +40,12 @@ class WebBrowserPersistDocumentParent final
   // is still in the START state (or is unconstructed).
   void SetOnReady(nsIWebBrowserPersistDocumentReceiver* aOnReady);
 
+  // True while the actor is in the START state and no callback has
+  // been attached to it yet.  Used to validate the sub-document actors
+  // that the child sends over PWebBrowserPersistResources, which are
+  // required to be freshly constructed.
+  bool IsUnclaimedStartState() const { return !mOnReady && !mReflection; }
+
   using Attrs = WebBrowserPersistDocumentAttrs;
 
   // IPDL methods:
diff --git a/dom/webbrowserpersist/WebBrowserPersistResourcesParent.cpp b/dom/webbrowserpersist/WebBrowserPersistResourcesParent.cpp
index 2ca65ce7ecc..ea5d1f216b3 100644
--- a/dom/webbrowserpersist/WebBrowserPersistResourcesParent.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistResourcesParent.cpp
@@ -55,10 +55,15 @@ mozilla::ipc::IPCResult WebBrowserPersistResourcesParent::RecvVisitResource(
 
 mozilla::ipc::IPCResult WebBrowserPersistResourcesParent::RecvVisitDocument(
     NotNull<PWebBrowserPersistDocumentParent*> aSubDocument) {
+  auto* subDocument =
+      static_cast<WebBrowserPersistDocumentParent*>(aSubDocument.get());
+  if (!subDocument->IsUnclaimedStartState()) {
+    return IPC_FAIL(this, "invalid subdocument actor state");
+  }
+
   // Don't expose the subdocument to the visitor until it's ready
   // (until the actor isn't in START state).
-  static_cast<WebBrowserPersistDocumentParent*>(aSubDocument.get())
-      ->SetOnReady(this);
+  subDocument->SetOnReady(this);
   return IPC_OK();
 }
 
Loading diff…