Firefox · Networking
CVE-2026-16405
Logic Error in Networking
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
FailDelaynetwerk/protocol/websocket/WebSocketChannel.cpp |
modified | |
ifnetwerk/protocol/websocket/WebSocketChannel.cpp |
modified |
Files Changed
netwerk/protocol/websocket/WebSocketChannel.cpp
Patch
diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp
index 5dd6161947f..618430282b1 100644
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -121,8 +121,12 @@ const uint32_t kWSReconnectMaxDelay = 60 * 1000;
// to same host/path/port.
class FailDelay {
public:
- FailDelay(nsCString address, nsCString path, int32_t port)
- : mAddress(std::move(address)), mPath(std::move(path)), mPort(port) {
+ FailDelay(nsCString address, nsCString path, int32_t port,
+ nsCString originSuffix)
+ : mAddress(std::move(address)),
+ mPath(std::move(path)),
+ mPort(port),
+ mOriginSuffix(std::move(originSuffix)) {
mLastFailure = TimeStamp::Now();
mNextDelay = kWSReconnectInitialBaseDelay +
(rand() % kWSReconnectInitialRandomDelay);
@@ -160,6 +164,7 @@ class FailDelay {
nsCString mAddress; // IP address (or hostname if using proxy)
nsCString mPath;
int32_t mPort;
+ nsCString mOriginSuffix;
private:
TimeStamp mLastFailure; // Time of last failed attempt
@@ -190,18 +195,20 @@ class FailDelayManager {
~FailDelayManager() { MOZ_COUNT_DTOR(FailDelayManager); }
- void Add(nsCString& address, nsCString& path, int32_t port) {
+ void Add(nsCString& address, nsCString& path, int32_t port,
+ nsCString& originSuffix) {
if (mDelaysDisabled) {
return;
}
- mEntries.AppendElement(MakeUnique<FailDelay>(address, path, port));
+ mEntries.AppendElement(
+ MakeUnique<FailDelay>(address, path, port, originSuffix));
}
// Element returned may not be valid after next main thread event: don't keep
// pointer to it around
FailDelay* Lookup(nsCString& address, nsCString& path, int32_t port,
- uint32_t* outIndex = nullptr) {
+ nsCString& originSuffix, uint32_t* outIndex = nullptr) {
if (mDelaysDisabled) {
return nullptr;
}
@@ -214,7 +221,7 @@ class FailDelayManager {
for (int32_t i = mEntries.Length() - 1; i >= 0; --i) {
FailDelay* fail = mEntries[i].get();
if (fail->mAddress.Equals(address) && fail->mPath.Equals(path) &&
- fail->mPort == port) {
+ fail->mPort == port && fail->mOriginSuffix.Equals(originSuffix)) {
if (outIndex) *outIndex = i;
result = fail;
// break here: removing more entries would mess up *outIndex.
@@ -233,7 +240,8 @@ class FailDelayManager {
void DelayOrBegin(WebSocketChannel* ws) {
if (!mDelaysDisabled) {
uint32_t failIndex = 0;
- FailDelay* fail = Lookup(ws->mAddress, ws->mPath, ws->mPort, &failIndex);
+ FailDelay* fail = Lookup(ws->mAddress, ws->mPath, ws->mPort,
+ ws->mOriginSuffix, &failIndex);
if (fail) {
TimeStamp rightNow = TimeStamp::Now();
@@ -269,14 +277,15 @@ class FailDelayManager {
// Remove() also deletes all expired entries as it iterates: better for
// battery life than using a periodic timer.
- void Remove(nsCString& address, nsCString& path, int32_t port) {
+ void Remove(nsCString& address, nsCString& path, int32_t port,
+ nsCString& originSuffix) {
TimeStamp rightNow = TimeStamp::Now();
// iterate from end, to make deletion indexing easier
for (int32_t i = mEntries.Length() - 1; i >= 0; --i) {
FailDelay* entry = mEntries[i].get();
if ((entry->mAddress.Equals(address) && entry->mPath.Equals(path) &&
- entry->mPort == port) ||
+ entry->mPort == port && entry->mOriginSuffix.Equals(originSuffix)) ||
entry->IsExpired(rightNow)) {
mEntries.RemoveElementAt(i);
}
@@ -328,8 +337,8 @@ class nsWSAdmissionManager {
bool hostFound = (sManager->IndexOf(ws->mAddress, ws->mOriginSuffix) >= 0);
uint32_t failIndex = 0;
- FailDelay* fail = sManager->mFailures.Lookup(ws->mAddress, ws->mPath,
- ws->mPort, &failIndex);
+ FailDelay* fail = sManager->mFailures.Lookup(
+ ws->mAddress, ws->mPath, ws->mPort, ws->mOriginSuffix, &failIndex);
bool existingFail = fail != nullptr;
// Always add ourselves to queue, even if we'll connect immediately
@@ -377,7 +386,7 @@ class nsWSAdmissionManager {
// Connection succeeded, so stop keeping track of any previous failures
sManager->mFailures.Remove(aChannel->mAddress, aChannel->mPath,
- aChannel->mPort);
+ aChannel->mPort, aChannel->mOriginSuffix);
// Check for queued connections to same host.
// Note: still need to check for failures, since next websocket with same
@@ -398,8 +407,9 @@ class nsWSAdmissionManager {
if (NS_FAILED(aReason)) {
// Have we seen this failure before?
- FailDelay* knownFailure = sManager->mFailures.Lookup(
- aChannel->mAddress, aChannel->mPath, aChannel->mPort);
+ FailDelay* knownFailure =
+ sManager->mFailures.Lookup(aChannel->mAddress, aChannel->mPath,
+ aChannel->mPort, aChannel->mOriginSuffix);
if (knownFailure) {
if (aReason == NS_ERROR_NOT_CONNECTED) {
// Don't count close() before connection as a network error
@@ -418,7 +428,7 @@ class nsWSAdmissionManager {
aChannel->mAddress.get(), aChannel->mPath.get(),
(int)aChannel->mPort, aChannel));
sManager->mFailures.Add(aChannel->mAddress, aChannel->mPath,
- aChannel->mPort);
+ aChannel->mPort, aChannel->mOriginSuffix);
}
}
Loading diff…
References
On This Page