Firefox · DOM
CVE-2026-74958
Logic Error in DOM
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdom/media/webrtc/transport/nr_socket_prsock.cpp |
modified | |
fordom/media/webrtc/transport/nr_socket_prsock.cpp |
modified | |
TEST_Fdom/media/webrtc/transport/test/test_nr_socket_unittest.cpp |
modified |
Files Changed
dom/media/webrtc/transport/nr_socket_prsock.cppdom/media/webrtc/transport/nr_socket_prsock.hdom/media/webrtc/transport/test/test_nr_socket_unittest.cpp
Patch
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…
References
On This Page