Firefox · Core
CVE-2026-6753
Logic Error in Core
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifthird_party/libwebrtc/net/dcsctp/tx/outstanding_data.cc |
modified |
Files Changed
third_party/libwebrtc/net/dcsctp/tx/outstanding_data.ccthird_party/libwebrtc/net/dcsctp/tx/outstanding_data.hthird_party/libwebrtc/net/dcsctp/tx/retransmission_queue.cc
Patch
diff --git a/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.cc b/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.cc
index 63e750b5fc3..8dbd3bc6855 100644
--- a/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.cc
+++ b/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.cc
@@ -143,6 +143,9 @@ OutstandingData::AckInfo OutstandingData::HandleSack(
UnwrappedTSN cumulative_tsn_ack,
webrtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
bool is_in_fast_recovery) {
+ bool cumulative_tsn_ack_advanced =
+ cumulative_tsn_ack > last_cumulative_tsn_ack_;
+
OutstandingData::AckInfo ack_info(cumulative_tsn_ack);
// Erase all items up to cumulative_tsn_ack.
RemoveAcked(cumulative_tsn_ack, ack_info);
@@ -152,7 +155,7 @@ OutstandingData::AckInfo OutstandingData::HandleSack(
// NACK and possibly mark for retransmit chunks that weren't acked.
NackBetweenAckBlocks(cumulative_tsn_ack, gap_ack_blocks, is_in_fast_recovery,
- ack_info);
+ cumulative_tsn_ack_advanced, ack_info);
RTC_DCHECK(IsConsistent());
return ack_info;
@@ -225,6 +228,7 @@ void OutstandingData::NackBetweenAckBlocks(
UnwrappedTSN cumulative_tsn_ack,
webrtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
bool is_in_fast_recovery,
+ bool cumulative_tsn_acked_advanced,
OutstandingData::AckInfo& ack_info) {
// Mark everything between the blocks as NACKED/TO_BE_RETRANSMITTED.
// https://tools.ietf.org/html/rfc4960#section-7.2.4
@@ -237,7 +241,7 @@ void OutstandingData::NackBetweenAckBlocks(
// in-flight and between gaps should be nacked. This means that SCTP relies on
// the T3-RTX-timer to re-send packets otherwise.
UnwrappedTSN max_tsn_to_nack = ack_info.highest_tsn_acked;
- if (is_in_fast_recovery && cumulative_tsn_ack > last_cumulative_tsn_ack_) {
+ if (is_in_fast_recovery && cumulative_tsn_acked_advanced) {
// https://tools.ietf.org/html/rfc4960#section-7.2.4
// "If an endpoint is in Fast Recovery and a SACK arrives that advances
// the Cumulative TSN Ack Point, the miss indications are incremented for
@@ -252,7 +256,8 @@ void OutstandingData::NackBetweenAckBlocks(
UnwrappedTSN cur_block_first_acked =
UnwrappedTSN::AddTo(cumulative_tsn_ack, block.start);
for (UnwrappedTSN tsn = prev_block_last_acked.next_value();
- tsn < cur_block_first_acked && tsn <= max_tsn_to_nack;
+ tsn < cur_block_first_acked && tsn <= max_tsn_to_nack &&
+ tsn < next_tsn();
tsn = tsn.next_value()) {
ack_info.has_packet_loss |=
NackItem(tsn, /*retransmit_now=*/false,
diff --git a/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h b/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h
index 512385e6fef..bfe668fbc54 100644
--- a/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h
+++ b/third_party/libwebrtc/net/dcsctp/tx/outstanding_data.h
@@ -325,6 +325,7 @@ class OutstandingData {
UnwrappedTSN cumulative_tsn_ack,
webrtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
bool is_in_fast_recovery,
+ bool cumulative_tsn_acked_advanced,
OutstandingData::AckInfo& ack_info);
// Process the acknowledgement of the chunk referenced by `iter` and updates
diff --git a/third_party/libwebrtc/net/dcsctp/tx/retransmission_queue.cc b/third_party/libwebrtc/net/dcsctp/tx/retransmission_queue.cc
index 9557a9be226..e3ed0e6da19 100644
--- a/third_party/libwebrtc/net/dcsctp/tx/retransmission_queue.cc
+++ b/third_party/libwebrtc/net/dcsctp/tx/retransmission_queue.cc
@@ -251,6 +251,14 @@ bool RetransmissionQueue::IsSackValid(const SackChunk& sack) const {
} else if (cumulative_tsn_ack > outstanding_data_.highest_outstanding_tsn()) {
return false;
}
+
+ for (const auto& block : sack.gap_ack_blocks()) {
+ if (UnwrappedTSN::AddTo(cumulative_tsn_ack, block.end) >
+ outstanding_data_.highest_outstanding_tsn()) {
+ return false;
+ }
+ }
+
return true;
}
Loading diff…
References
On This Page