High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionSandbox escape due to use-after-free in the DOM: Security component
ComponentLayout
Bug ClassLogic Error
Tracker2059018
Fix commit90bed268089a (firefox) +58/-7
CISA KEVNot listed
CreditedYaqoub Aldurayhim
Disclosed2026-09-01

Files Changed

  • image/decoders/icon/components.conf
  • layout/build/components.conf
  • modules/libjar/components.conf
  • netwerk/build/components.conf
  • security/manager/ssl/components.conf
  • xpcom/components/StaticComponents.h
  • xpcom/components/gen_static_components.py
  • xpcom/io/moz.build
  • xpcom/io/nsBinaryStream.cpp
diff --git a/image/decoders/icon/components.conf b/image/decoders/icon/components.conf
index 9bac3483e60..ecfd64a09f6 100644
--- a/image/decoders/icon/components.conf
+++ b/image/decoders/icon/components.conf
@@ -23,5 +23,6 @@ Classes = [
         'cid': '{1460df3b-774c-4205-8349-838e507c3ef9}',
         'type': 'nsMozIconURI::Mutator',
         'headers': ['/image/decoders/icon/nsIconURI.h'],
+        'serializable': True,
     },
 ]
diff --git a/layout/build/components.conf b/layout/build/components.conf
index de302238380..791222eb1e9 100644
--- a/layout/build/components.conf
+++ b/layout/build/components.conf
@@ -52,11 +52,13 @@ Classes = [
         'cid': '{574ce83e-fe9f-4095-b85c-7909abbf7c37}',
         'type': 'nsJSURI::Mutator',
         'headers': ['nsJSProtocolHandler.h'],
+        'serializable': True,
     },
     {
         'cid': '{58f089ee-512a-42d2-a935-d0c874128930}',
         'type': 'nsJSURI::Mutator',
         'headers': ['nsJSProtocolHandler.h'],
+        'serializable': True,
     },
     {
         'cid': '{48118355-e9a5-4452-ab18-59cc426fb817}',
@@ -71,11 +73,13 @@ Classes = [
         'cid': '{bbe50ef2-80eb-469d-b70d-02858275389f}',
         'type': 'mozilla::dom::BlobURL::Mutator',
         'headers': ['mozilla/dom/BlobURL.h'],
+        'serializable': True,
     },
     {
         'cid': '{f5475c51-59a7-4757-b3d9-e211a9410872}',
         'type': 'mozilla::dom::BlobURL::Mutator',
         'headers': ['mozilla/dom/BlobURL.h'],
+        'serializable': True,
     },
     {
         'js_name': 'cpmm',
@@ -113,6 +117,7 @@ Classes = [
         'contract_ids': ['@mozilla.org/cspcontext;1'],
         'type': 'nsCSPContext',
         'headers': ['mozilla/dom/nsCSPContext.h'],
+        'serializable': True,
     },
     {
         'cid': '{8d2f40b2-4875-4c95-97d9-3f7dca2cb460}',
@@ -126,6 +131,7 @@ Classes = [
         'contract_ids': ['@mozilla.org/integritypolicy;1'],
         'type': 'mozilla::dom::IntegrityPolicy',
         'headers': ['mozilla/dom/IntegrityPolicy.h'],
+        'serializable': True,
     },
     {
         'cid': '{3662958c-0e34-4f57-bc6d-2accdeb4342e}',
@@ -139,6 +145,7 @@ Classes = [
         'contract_ids': ['@mozilla.org/policycontainer;1'],
         'type': 'PolicyContainer',
         'headers': ['mozilla/dom/PolicyContainer.h'],
+        'serializable': True,
     },
     {
         'cid': '{1147d32c-215b-4014-b180-07fe7aedf915}',
@@ -208,6 +215,7 @@ Classes = [
         'contract_ids': [],
         'type': 'ExpandedPrincipal::Deserializer',
         'headers': ['/caps/ExpandedPrincipal.h'],
+        'serializable': True,
     },
     {
         'js_name': 'focus',
@@ -305,6 +313,7 @@ Classes = [
         'contract_ids': ['@mozilla.org/referrer-info;1'],
         'type': 'mozilla::dom::ReferrerInfo',
         'headers': ['mozilla/dom/ReferrerInfo.h'],
+        'serializable': True,
     },
     {
         'cid': '{bfc310d2-38a0-11d3-8cd3-0060b0fc14a3}',
@@ -335,6 +344,7 @@ Classes = [
         'contract_ids': [],
         'type': 'mozilla::NullPrincipal::Deserializer',
         'headers': ['/caps/NullPrincipal.h'],
+        'serializable': True,
     },
     {
         'js_name': 'ppmm',
@@ -353,6 +363,7 @@ Classes = [
         'contract_ids': [],
         'type': 'mozilla::ContentPrincipal::Deserializer',
         'headers': ['/caps/ContentPrincipal.h'],
+        'serializable': True,
     },
     {
         'cid': '{f68037ec-2790-44c5-8e5f-df5da58b93a7}',
@@ -399,6 +410,7 @@ Classes = [
         'type': 'nsIPrincipal',
         'headers': ['nsScriptSecurityManager.h', '/caps/SystemPrincipal.h'],
         'constructor': 'nsScriptSecurityManager::SystemPrincipalSingletonConstructor',
+        'serializable': True,
     },
     {
         'cid': '{caaab47f-1e31-478e-8919-970904e9cb72}',
diff --git a/modules/libjar/components.conf b/modules/libjar/components.conf
index a2f231f235a..38f8638c346 100644
--- a/modules/libjar/components.conf
+++ b/modules/libjar/components.conf
@@ -32,11 +32,13 @@ Classes = [
         'cid': '{245abae2-b947-4ded-a46d-9829d3cca462}',
         'type': 'nsJARURI::Mutator',
         'headers': ['nsJARURI.h'],
+        'serializable': True,
     },
     {
         'cid': '{19d9161b-a2a9-4518-b2c9-fcb8296d6dcd}',
         'type': 'nsJARURI::Mutator',
         'headers': ['nsJARURI.h'],
+        'serializable': True,
     },
     {
         'cid': '{608b7f6f-4b60-40d6-87ed-d933bf53d8c1}',
diff --git a/netwerk/build/components.conf b/netwerk/build/components.conf
index f0a998f6da3..660fbb2eaad 100644
--- a/netwerk/build/components.conf
+++ b/netwerk/build/components.conf
@@ -604,6 +604,7 @@ Classes = [
         'type': 'mozilla::net::nsSimpleURI::Mutator',
         'headers': ['nsSimpleURI.h'],
         'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
+        'serializable': True,
     },
     {
         'cid': '{04445aa0-fd27-4c99-bd41-6be6318ae92c}',
@@ -611,6 +612,7 @@ Classes = [
         'type': 'mozilla::net::DefaultURI::Mutator',
         'headers': ['/netwerk/base/DefaultURI.h'],
         'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
+        'serializable': True,
     },
     {
         'name': 'SocketTransport',
@@ -628,6 +630,7 @@ Classes = [
         'type': 'mozilla::net::nsStandardURL::Mutator',
         'headers': ['/netwerk/base/nsStandardURL.h'],
         'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
+        'serializable': True,
     },
     {
         'cid': '{831f8f13-7aa8-485f-b02e-77c881cc5773}',
@@ -743,30 +746,35 @@ Classes = [
         'contract_ids': [],
         'type': 'mozilla::net::nsNestedAboutURI::Mutator',
         'headers': ['/netwerk/protocol/about/nsAboutProtocolHandler.h'],
+        'serializable': True,
     },
     {
         'cid': '{56388dad-287b-4240-a785-85c394012503}',
         'contract_ids': [],
         'type': 'mozilla::net::nsSimpleNestedURI::Mutator',
         'headers': ['nsSimpleNestedURI.h'],
+        'serializable': True,
     },
     {
         'cid': '{9c4e9d49-ce64-4ca3-acef-3075c5e5aba7}',
         'contract_ids': [],
         'type': 'mozilla::net::nsSimpleNestedURI::Mutator',
         'headers': ['nsSimpleNestedURI.h'],
+        'serializable': True,
     },
     {
         'cid': '{b0054ef3-b096-483d-8242-4ee36b7b2115}',
         'contract_ids': [],
         'type': 'mozilla::net::nsNestedAboutURI::Mutator',
         'headers': ['/netwerk/protocol/about/nsAboutProtocolHandler.h'],
+        'serializable': True,
     },
     {
         'cid': '{b3cfeb91-332a-46c9-ad97-93ff39841494}',
         'contract_ids': [],
         'type': 'mozilla::net::SubstitutingURL::Mutator',
         'headers': ['mozilla/net/SubstitutingURL.h'],
+        'serializable': True,
     },
     {
         'cid': '{de9472d0-8034-11d3-9399-00104ba0fd40}',
@@ -774,12 +782,14 @@ Classes = [
         'type': 'mozilla::net::nsStandardURL::Mutator',
         'headers': ['/netwerk/base/nsStandardURL.h'],
         'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
+        'serializable': True,
     },
     {
         'cid': '{dea9657c-18cf-4984-bde9-ccef5d8ab473}',
         'contract_ids': [],
         'type': 'mozilla::net::SubstitutingURL::Mutator',
         'headers': ['mozilla/net/SubstitutingURL.h'],
+        'serializable': True,
     },
     {
         'cid': '{50d50ddf-f16a-4652-8705-936b19c3763b}',
@@ -787,6 +797,7 @@ Classes = [
         'type': 'mozilla::net::SubstitutingJARURI',
         'headers': ['mozilla/net/SubstitutingJARURI.h'],
         'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
+        'serializable': True,
     },
     {
         'cid': '{e0da1d70-2f7b-11d3-8cd0-0060b0fc14a3}',
@@ -794,6 +805,7 @@ Classes = [
         'type': 'mozilla::net::nsSimpleURI::Mutator',
         'headers': ['nsSimpleURI.h'],
         'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
+        'serializable': True,
     },
     {
         'js_name': 'cookies',
@@ -821,6 +833,7 @@ Classes = [
         'type': 'nsICookieJarSettings',
         'constructor': 'mozilla::net::CookieJarSettings::CreateForXPCOM',
         'headers': ['mozilla/net/CookieJarSettings.h'],
+        'serializable': True,
     },
     {
         'cid': '{86606ba1-de17-4df4-9013-e571ab94fd94}',
diff --git a/security/manager/ssl/components.conf b/security/manager/ssl/components.conf
index 56dd91cd314..49b37f31cb7 100644
--- a/security/manager/ssl/components.conf
+++ b/security/manager/ssl/components.conf
@@ -57,6 +57,7 @@ Classes = [
         'contract_ids': [],
         'type': 'nsNSSCertificate',
         'headers': ['nsNSSCertificate.h'],
+        'serializable': True,
     },
     {
         'name': 'NSSCertificateDB',
diff --git a/xpcom/components/StaticComponents.h b/xpcom/components/StaticComponents.h
index 30efd4a81c9..da2be9d3c1d 100644
--- a/xpcom/components/StaticComponents.h
+++ b/xpcom/components/StaticComponents.h
@@ -94,6 +94,9 @@ struct StaticModule {
   StringOffset mContractID;
   Module::ProcessSelector mProcessSelector;
 
+  // Does the object returned by CreateInstance implement nsISerializable?
+  bool mIsSerializable;
+
   const nsID& CID() const { return mCID; }
 
   ModuleID ID() const { return ModuleID(this - gStaticModules); }
diff --git a/xpcom/components/gen_static_components.py b/xpcom/components/gen_static_components.py
index 95c39dd0d84..f36b0a4e401 100644
--- a/xpcom/components/gen_static_components.py
+++ b/xpcom/components/gen_static_components.py
@@ -294,6 +294,7 @@ class ModuleEntry:
         )
         self.singleton = data.get("singleton", False)
         self.overridable = data.get("overridable", False)
+        self.serializable = data.get("serializable", False)
 
         self.protocol_config = data.get("protocol_config", None)
 
@@ -365,6 +366,7 @@ class ModuleEntry:
           {self.cid.to_cxx()},
           {contract_id},
           {lower_processes(self.processes)},
+          {"true" if self.serializable else "false"},
         }}"""
 
     # Generates the C++ code for a JSServiceEntry representing this module.
diff --git a/xpcom/io/moz.build b/xpcom/io/moz.build
index 13fedb6eccf..bafdea29977 100644
--- a/xpcom/io/moz.build
+++ b/xpcom/io/moz.build
@@ -176,6 +176,8 @@ if CONFIG["OS_ARCH"] == "Linux" and "lib64" in CONFIG["libdir"]:
 
 LOCAL_INCLUDES += [
     "!..",
+    "!../components",
     "../build",
+    "../components",
     "/toolkit/xre",
 ]
diff --git a/xpcom/io/nsBinaryStream.cpp b/xpcom/io/nsBinaryStream.cpp
index cc92c27954d..256d87c1c43 100644
--- a/xpcom/io/nsBinaryStream.cpp
+++ b/xpcom/io/nsBinaryStream.cpp
@@ -22,6 +22,7 @@
 
 #include <algorithm>
 
+#include "StaticComponents.h"
 #include "js/ArrayBuffer.h"  // JS::{GetArrayBuffer{,ByteLength},IsArrayBufferObject}
 #include "js/ArrayBufferMaybeShared.h"  // JS::IsImmutableArrayBufferMaybeShared
 #include "js/GCAPI.h"                   // JS::AutoCheckCannotGC
@@ -47,6 +48,12 @@ using mozilla::PodCopy;
 using mozilla::Span;
 using mozilla::UniquePtr;
 
+static bool IsCIDSerializable(const nsID& aCID) {
+  const mozilla::xpcom::StaticModule* module =
+      mozilla::xpcom::StaticComponents::LookupByCID(aCID);
+  return module && module->mIsSerializable;
+}
+
 already_AddRefed<nsIObjectOutputStream> NS_NewObjectOutputStream(
     nsIOutputStream* aOutputStream) {
   MOZ_ASSERT(aOutputStream);
@@ -308,20 +315,24 @@ nsBinaryOutputStream::WriteCompoundObject(nsISupports* aObject,
 
   nsCID cid;
   nsresult rv = classInfo->GetClassIDNoAlloc(&cid);
-  if (NS_SUCCEEDED(rv)) {
-    rv = WriteID(cid);
-  } else {
-    nsCID* cidptr = nullptr;
-    rv = classInfo->GetClassID(&cidptr);
+  if (NS_FAILED(rv)) {
+    std::unique_ptr<nsCID> cidptr;
+    rv = classInfo->GetClassID(mozilla::getter_Transfers(cidptr));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
-    rv = WriteID(*cidptr);
+    cid = *cidptr;
+  }
 
-    free(cidptr);
+  if (NS_WARN_IF(!IsCIDSerializable(cid))) {
+    MOZ_ASSERT_UNREACHABLE(
+        "static component entry was not marked as serializable for "
+        "nsISerializable");
+    return NS_ERROR_NOT_AVAILABLE;
   }
 
+  rv = WriteID(cid);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
@@ -952,6 +963,10 @@ nsBinaryInputStream::ReadObject(bool aIsStrongRef, nsISupports** aObject) {
   }
   // END HACK
 
+  if (NS_WARN_IF(!IsCIDSerializable(cid))) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   nsCOMPtr<nsISupports> object = do_CreateInstance(cid, &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
Loading diff…