Medium firefox Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionSite isolation issue in the Networking: HTTP component
ComponentNetworking
Bug ClassLogic Error
Tracker2032140
Fix commit2ebc5198bee4 (firefox) +39/-5
CISA KEVNot listed
Creditedpakhunov.anton.n
Disclosed2026-07-21

Files Changed

  • ipc/glue/BackgroundParentImpl.cpp
  • netwerk/protocol/http/BackgroundChannelRegistrar.cpp
  • netwerk/protocol/http/HttpBackgroundChannelParent.cpp
  • netwerk/protocol/http/HttpBackgroundChannelParent.h
  • netwerk/protocol/http/HttpChannelParent.cpp
  • netwerk/protocol/http/HttpChannelParent.h
diff --git a/ipc/glue/BackgroundParentImpl.cpp b/ipc/glue/BackgroundParentImpl.cpp
index 292e261ee48..a401403b92c 100644
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -1073,7 +1073,12 @@ BackgroundParentImpl::RecvPHttpBackgroundChannelConstructor(
   net::HttpBackgroundChannelParent* aParent =
       static_cast<net::HttpBackgroundChannelParent*>(aActor);
 
-  if (NS_WARN_IF(NS_FAILED(aParent->Init(aChannelId)))) {
+  // Record the content process that owns this PBackground actor, so the
+  // background channel can only ever be paired with a HttpChannelParent
+  // from the same process.
+  dom::ContentParentId cpId(BackgroundParent::GetChildID(this));
+
+  if (NS_WARN_IF(NS_FAILED(aParent->Init(cpId, aChannelId)))) {
     return IPC_FAIL_NO_REASON(this);
   }
 
diff --git a/netwerk/protocol/http/BackgroundChannelRegistrar.cpp b/netwerk/protocol/http/BackgroundChannelRegistrar.cpp
index 960ce95715a..b397c9235de 100644
--- a/netwerk/protocol/http/BackgroundChannelRegistrar.cpp
+++ b/netwerk/protocol/http/BackgroundChannelRegistrar.cpp
@@ -48,6 +48,13 @@ void BackgroundChannelRegistrar::NotifyChannelLinked(
   MOZ_ASSERT(aChannelParent);
   MOZ_ASSERT(aBgParent);
 
+  // Only link the two actors when they originate from the same content
+  // process, since the channel Id used as the key is supplied by
+  // the content process.
+  if (aChannelParent->GetContentParentId() != aBgParent->GetContentParentId()) {
+    return;
+  }
+
   aBgParent->LinkToChannel(aChannelParent);
   aChannelParent->OnBackgroundParentReady(aBgParent);
 }
diff --git a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
index 22c60ffedc0..5b198b8380d 100644
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
@@ -79,12 +79,15 @@ HttpBackgroundChannelParent::~HttpBackgroundChannelParent() {
   MOZ_ASSERT(!mIPCOpened);
 }
 
-nsresult HttpBackgroundChannelParent::Init(const uint64_t& aChannelId) {
+nsresult HttpBackgroundChannelParent::Init(const dom::ContentParentId& aCpId,
+                                           const uint64_t& aChannelId) {
   LOG(("HttpBackgroundChannelParent::Init [this=%p channelId=%" PRIu64 "]\n",
        this, aChannelId));
   AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
 
+  mContentParentId = aCpId;
+
   RefPtr<ContinueAsyncOpenRunnable> runnable =
       new ContinueAsyncOpenRunnable(this, aChannelId);
 
diff --git a/netwerk/protocol/http/HttpBackgroundChannelParent.h b/netwerk/protocol/http/HttpBackgroundChannelParent.h
index db89d0f240e..31aa564d18b 100644
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.h
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.h
@@ -8,6 +8,7 @@
 #include "mozilla/net/PHttpBackgroundChannelParent.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/Mutex.h"
+#include "mozilla/dom/ipc/IdType.h"
 #include "nsID.h"
 #include "nsISupportsImpl.h"
 
@@ -24,9 +25,14 @@ class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent {
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HttpBackgroundChannelParent, final)
 
-  // Try to find associated HttpChannelParent with the same
-  // channel Id.
-  nsresult Init(const uint64_t& aChannelId);
+  // Try to find associated HttpChannelParent with the same content process
+  // and channel Id.
+  nsresult Init(const dom::ContentParentId& aCpId, const uint64_t& aChannelId);
+
+  // The content process that opened this background channel. Used by
+  // BackgroundChannelRegistrar to ensure the channel is only linked to a
+  // HttpChannelParent belonging to the same process.
+  dom::ContentParentId GetContentParentId() const { return mContentParentId; }
 
   // Callbacks for BackgroundChannelRegistrar to notify
   // the associated HttpChannelParent is found.
@@ -112,6 +118,10 @@ class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent {
   nsCOMPtr<nsISerialEventTarget> mBackgroundThread
       MOZ_GUARDED_BY(mBgThreadMutex);
 
+  // The content process that opened this background channel, set once in Init
+  // before the actor is registered.
+  dom::ContentParentId mContentParentId;
+
   // associated HttpChannelParent for generating the channel events
   RefPtr<HttpChannelParent> mChannelParent;
 };
diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
index bd284f6345f..f2e8d562495 100644
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -212,6 +212,10 @@ void HttpChannelParent::TryInvokeAsyncOpen(nsresult aRv) {
   InvokeAsyncOpen(aRv);
 }
 
+dom::ContentParentId HttpChannelParent::GetContentParentId() const {
+  return static_cast<ContentParent*>(Manager()->Manager())->ChildID();
+}
+
 void HttpChannelParent::OnBackgroundParentReady(
     HttpBackgroundChannelParent* aBgParent) {
   LOG(("HttpChannelParent::OnBackgroundParentReady [this=%p bgParent=%p]\n",
diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h
index 9f48ab236e2..3fd64fd0c8b 100644
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -102,6 +102,11 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
                                 const nsACString& aPromptAction,
                                 const nsACString& aTopLevelSite);
 
+  // The content process this channel parent belongs to. Used by
+  // BackgroundChannelRegistrar to ensure a background channel is only linked
+  // to a channel from the same process.
+  dom::ContentParentId GetContentParentId() const;
+
   // Callback while background channel is ready.
   void OnBackgroundParentReady(HttpBackgroundChannelParent* aBgParent);
   // Callback while background channel is destroyed.
Loading diff…