Fix potential dcSCTP NackBetweenAckBlocks OOB access Add strict GapAckBlock boundary validation in RetransmissionQueue::IsSackValid to drop malformed SACK chunks that acknowledge TSNs beyond the currently outstanding sequence numbers. Additionally, adds bounds checking within NackBetweenAckBlocks to prevent Out-Of-Bounds iterating. Bug: webrtc:495700476 Change-Id: I6ca4011cd074ef3777ff972488dad79227e6d45b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/460720 Reviewed-by: Victor Boivie <boivie@webrtc.org> Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#47283}
diff --git a/net/dcsctp/tx/outstanding_data.cc b/net/dcsctp/tx/outstanding_data.cc index 89f1ea2..b996dbd 100644 --- a/net/dcsctp/tx/outstanding_data.cc +++ b/net/dcsctp/tx/outstanding_data.cc
@@ -256,7 +256,8 @@ 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/net/dcsctp/tx/outstanding_data_test.cc b/net/dcsctp/tx/outstanding_data_test.cc index f56f1d5..7818d9b 100644 --- a/net/dcsctp/tx/outstanding_data_test.cc +++ b/net/dcsctp/tx/outstanding_data_test.cc
@@ -732,5 +732,20 @@ Pair(TSN(16), State::kAcked))); } +TEST_F(OutstandingDataTest, NackBetweenAckBlocksDoesNotAccessOutOfBounds) { + for (int i = 0; i < 5; ++i) { + buf_.Insert(kMessageId, gen_.Ordered({1}, ""), kNow); + } + + // Inject a malformed SACK where the GapAckBlock exceeds the number of + // outstanding items, potentially triggering an OOB read/write. + std::vector<SackChunk::GapAckBlock> malformed_blocks = { + SackChunk::GapAckBlock(1, 40000)}; + + // This should not crash or trigger ASAN errors. + buf_.HandleSack(unwrapper_.Unwrap(TSN(10)), malformed_blocks, + /*is_in_fast_recovery=*/false); +} + } // namespace } // namespace dcsctp
diff --git a/net/dcsctp/tx/retransmission_queue.cc b/net/dcsctp/tx/retransmission_queue.cc index 3dc2bc7..2cfc6ef 100644 --- a/net/dcsctp/tx/retransmission_queue.cc +++ b/net/dcsctp/tx/retransmission_queue.cc
@@ -250,6 +250,14 @@ } 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; }