Medium firefox Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionInformation disclosure in the WebRTC component
ComponentDOM
Bug ClassLogic Error
Tracker2045368
Fix commit1684bd5486af (firefox) +46/-8
CISA KEVNot listed
CreditedTomoya Nakanishi
Disclosed2026-08-18

Changed Functions

FunctionChangeNotes
if
dom/media/webrtc/transport/nr_socket_prsock.cpp
modified
for
dom/media/webrtc/transport/nr_socket_prsock.cpp
modified
TEST_F
dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
modified

Files Changed

  • dom/media/webrtc/transport/nr_socket_prsock.cpp
  • dom/media/webrtc/transport/nr_socket_prsock.h
  • dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
diff --git a/dom/media/webrtc/transport/nr_socket_prsock.cpp b/dom/media/webrtc/transport/nr_socket_prsock.cpp
index 0933f80851c..fcf4029506f 100644
--- a/dom/media/webrtc/transport/nr_socket_prsock.cpp
+++ b/dom/media/webrtc/transport/nr_socket_prsock.cpp
@@ -88,6 +88,7 @@ nrappkit copyright:
 #include <string.h>
 #include <sys/types.h>
 
+#include "mozilla/IceServerParser.h"
 #include "mozilla/ProfilerBandwidthCounter.h"
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/net/DNS.h"
@@ -743,6 +744,16 @@ int NrSocket::sendto(const void* msg, size_t len, int flags,
     ABORT(R_WOULDBLOCK);
   }
 
+  // Block outgoing packets to ports that are not allowed for webrtc. This runs
+  // in whatever process opened the socket -- the socket process (socket-process
+  // mtransport) or the parent process -- never the content process, which uses
+  // NrUdpSocketIpc/NrTcpSocket.
+  if (IsForbiddenAddress(to)) {
+    // Drop the packet, but report success so the caller does not retry.
+    _status = 0;
+    goto abort;
+  }
+
   // TODO: Convert flags?
   status = PR_SendTo(fd_, msg, len, flags, &naddr, PR_INTERVAL_NO_WAIT);
   if (status < 0 || (size_t)status != len) {
@@ -808,6 +819,12 @@ int NrSocket::connect(const nr_transport_addr* addr) {
 
   if (!fd_) ABORT(R_EOD);
 
+  // Block connections to ports that are not allowed for webrtc. See the note
+  // in NrSocket::sendto; this runs only in the socket/parent process.
+  if (IsForbiddenAddress(addr)) {
+    ABORT(R_WOULDBLOCK);
+  }
+
   // Note: this just means we tried to connect, not that we
   // are actually live.
   connect_invoked_ = true;
@@ -1599,7 +1616,7 @@ abort:
 }
 
 // static
-bool NrSocketBase::IsForbiddenAddress(nr_transport_addr* addr) {
+bool NrSocketBase::IsForbiddenAddress(const nr_transport_addr* addr) {
   uint16_t port;
   int r;
 
@@ -1609,15 +1626,20 @@ bool NrSocketBase::IsForbiddenAddress(nr_transport_addr* addr) {
   }
 
   // allow auto assigned ports
-  if (port != 0) {
-    // Don't need to check an override scheme
-    nsresult rv = NS_CheckPortSafety(port, nullptr);
-    if (NS_FAILED(rv)) {
-      return true;
+  if (port == 0) {
+    return false;
+  }
+
+  // First check the known good ports for webrtc.
+  for (const auto good : IceServerParser::kGoodWebrtcPortList) {
+    if (port == good) {
+      return false;
     }
   }
 
-  return false;
+  // Otherwise fall back to Necko's generic outgoing port block list. Don't
+  // need to check an override scheme.
+  return NS_FAILED(NS_CheckPortSafety(port, nullptr));
 }
 
 static int nr_socket_local_destroy(void** objp) {
diff --git a/dom/media/webrtc/transport/nr_socket_prsock.h b/dom/media/webrtc/transport/nr_socket_prsock.h
index 11cfd74b16a..929c68ce814 100644
--- a/dom/media/webrtc/transport/nr_socket_prsock.h
+++ b/dom/media/webrtc/transport/nr_socket_prsock.h
@@ -99,7 +99,7 @@ class NrSocketBase {
   // NrTcpSocketIpc as appropriate.
   static int CreateSocket(nr_transport_addr* addr, RefPtr<NrSocketBase>* sock,
                           const std::shared_ptr<NrSocketProxyConfig>& config);
-  static bool IsForbiddenAddress(nr_transport_addr* addr);
+  static bool IsForbiddenAddress(const nr_transport_addr* addr);
 
   // the nr_socket APIs
   virtual int create(nr_transport_addr* addr) = 0;
diff --git a/dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp b/dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
index 02fa550a35b..5a670996bed 100644
--- a/dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
+++ b/dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
@@ -425,6 +425,22 @@ TEST_F(TestNrSocketTest, SafePortAcceptedTCP) {
   ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
 }
 
+TEST_F(TestNrSocketTest, WebrtcGoodPortAcceptedUDP) {
+  nr_transport_addr address;
+  // Port 53 is on Necko's generic block list but is explicitly allowed for
+  // webrtc to allow punching through overzealous NATs.
+  ASSERT_FALSE(
+      nr_str_port_to_transport_addr("127.0.0.1", 53, IPPROTO_UDP, &address));
+  ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
+}
+
+TEST_F(TestNrSocketTest, WebrtcGoodPortAcceptedTCP) {
+  nr_transport_addr address;
+  ASSERT_FALSE(
+      nr_str_port_to_transport_addr("127.0.0.1", 53, IPPROTO_TCP, &address));
+  ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
+}
+
 TEST_F(TestNrSocketTest, PublicConnectivity) {
   CreatePublicAddrs(2);
 
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp b/dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
index 02fa550a35b..5a670996bed 100644
--- a/dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
+++ b/dom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
@@ -425,6 +425,22 @@ TEST_F(TestNrSocketTest, SafePortAcceptedTCP) {
   ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
 }
 
+TEST_F(TestNrSocketTest, WebrtcGoodPortAcceptedUDP) {
+  nr_transport_addr address;
+  // Port 53 is on Necko's generic block list but is explicitly allowed for
+  // webrtc to allow punching through overzealous NATs.
+  ASSERT_FALSE(
+      nr_str_port_to_transport_addr("127.0.0.1", 53, IPPROTO_UDP, &address));
+  ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
+}
+
+TEST_F(TestNrSocketTest, WebrtcGoodPortAcceptedTCP) {
+  nr_transport_addr address;
+  ASSERT_FALSE(
+      nr_str_port_to_transport_addr("127.0.0.1", 53, IPPROTO_TCP, &address));
+  ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
+}
+
 TEST_F(TestNrSocketTest, PublicConnectivity) {
   CreatePublicAddrs(2);
Loading diff…