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 Disability Access APIs component
ComponentCore
Bug ClassLogic Error
Tracker2056767
Fix commit715cafa4f852 (firefox) +24/-8
CISA KEVNot listed
CreditedMozilla
Disclosed2026-09-29

Changed Functions

FunctionChangeNotes
if
accessible/base/DocManager.cpp
modified

Files Changed

  • accessible/base/DocManager.cpp
  • accessible/ipc/DocAccessibleParent.cpp
diff --git a/accessible/base/DocManager.cpp b/accessible/base/DocManager.cpp
index 8264f3d95b7..ffe8ab2f068 100644
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -34,6 +34,10 @@
 #include "nsIWebProgress.h"
 #include "xpcAccessibleDocument.h"
 
+#if defined(ANDROID)
+#  include "mozilla/Monitor.h"
+#endif
+
 using namespace mozilla;
 using namespace mozilla::a11y;
 using namespace mozilla::dom;
@@ -275,6 +279,18 @@ void DocManager::Shutdown() {
   }
 
   ClearDocCache();
+  // Even though remote documents aren't strictly managed by this DocManager
+  // instance, destroy them now because they might depend on platform specific
+  // state which is about to be torn down by PlatformShutdown. Iterate the array
+  // backwards because destroying the document removes it from this array.
+  if (sRemoteDocuments) {
+#if defined(ANDROID)
+    MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
+#endif
+    for (size_t i = sRemoteDocuments->Length(); i-- > 0;) {
+      (*sRemoteDocuments)[i]->Destroy();
+    }
+  }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/accessible/ipc/DocAccessibleParent.cpp b/accessible/ipc/DocAccessibleParent.cpp
index 259503b5043..7ab1feabe1a 100644
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -1319,15 +1319,14 @@ void DocAccessibleParent::MaybeInitWindowEmulation() {
     isActive = GetBrowsingContext()->IsActive();
   }
 
-  // onCreate is guaranteed to be called synchronously by
-  // nsWinUtils::CreateNativeWindow, so this reference isn't really necessary.
-  // However, static analysis complains without it.
   RefPtr<DocAccessibleParent> thisRef = this;
-  nsWinUtils::NativeWindowCreateProc onCreate([thisRef](HWND aHwnd) -> void {
-    ::SetPropW(aHwnd, kPropNameDocAccParent,
-               reinterpret_cast<HANDLE>(thisRef.get()));
-    thisRef->SetEmulatedWindowHandle(aHwnd);
-  });
+  nsWinUtils::NativeWindowCreateProc onCreate(
+      [thisRef](HWND aHwnd) mutable -> void {
+        thisRef->SetEmulatedWindowHandle(aHwnd);
+        HANDLE val;
+        thisRef.forget(&val);  // Release in SetEmulatedWindowHandle.
+        ::SetPropW(aHwnd, kPropNameDocAccParent, val);
+      });
 
   HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
   DebugOnly<HWND> hWnd = nsWinUtils::CreateNativeWindow(
@@ -1339,6 +1338,7 @@ void DocAccessibleParent::MaybeInitWindowEmulation() {
 void DocAccessibleParent::SetEmulatedWindowHandle(HWND aWindowHandle) {
   if (!aWindowHandle && mEmulatedWindowHandle && IsTopLevel()) {
     ::DestroyWindow(mEmulatedWindowHandle);
+    Release();  // AddRef in MaybeInitWindowEmulation.
   }
   mEmulatedWindowHandle = aWindowHandle;
 }
Loading diff…