mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00

If a FORWARD-TSN contains an ordered skipped stream with a large TSN but with a too small SSN, it can result in messages being assembled that should've been skipped. Typically: Receive DATA, ordered, complete, TSN=10, SID=1, SSN=0 - will be delivered. Receive DATA, ordered, complete, TSN=43, SID=1, SSN=7 - will stay in queue, due to missing SSN=1,2,3,4,5,6. Receive FORWARD-TSN, TSN=44, SSN=6 - is invalid, as the SSN should've been 7 or higher. However, as the TSN isn't used for removing messages in ordered streams, but just the SSN, the SSN=7 isn't removed but instead will be delivered as it's the next following SSN after 6. This will trigger internal consistency checks as a chunk with TSN=43 will be delivered when the current cumulative TSN is set to 44, which is greater. This was found when fuzzing, and can only be provoked by a client that is intentionally misbehaving. Before this fix, there was no harm done, but it failed consistency checks which fuzzers have enabled. When bug 13799 was fixed (in a previous commit), this allowed the fuzzers to find it faster. Bug: webrtc:13799 Change-Id: I830ef189476e227e1dbe08157d34f96ad6453e30 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/254240 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Victor Boivie <boivie@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36157}
64 lines
2 KiB
C++
64 lines
2 KiB
C++
/*
|
|
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
#include "api/array_view.h"
|
|
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
|
|
#include "net/dcsctp/testing/testing_macros.h"
|
|
#include "rtc_base/gunit.h"
|
|
#include "test/gmock.h"
|
|
|
|
namespace dcsctp {
|
|
namespace {
|
|
using ::testing::ElementsAre;
|
|
|
|
TEST(ForwardTsnChunkTest, FromCapture) {
|
|
/*
|
|
FORWARD_TSN chunk(Cumulative TSN: 1905748778)
|
|
Chunk type: FORWARD_TSN (192)
|
|
Chunk flags: 0x00
|
|
Chunk length: 8
|
|
New cumulative TSN: 1905748778
|
|
*/
|
|
|
|
uint8_t data[] = {0xc0, 0x00, 0x00, 0x08, 0x71, 0x97, 0x6b, 0x2a};
|
|
|
|
ASSERT_HAS_VALUE_AND_ASSIGN(ForwardTsnChunk chunk,
|
|
ForwardTsnChunk::Parse(data));
|
|
EXPECT_EQ(*chunk.new_cumulative_tsn(), 1905748778u);
|
|
}
|
|
|
|
TEST(ForwardTsnChunkTest, SerializeAndDeserialize) {
|
|
ForwardTsnChunk chunk(
|
|
TSN(123), {ForwardTsnChunk::SkippedStream(StreamID(1), SSN(23)),
|
|
ForwardTsnChunk::SkippedStream(StreamID(42), SSN(99))});
|
|
|
|
std::vector<uint8_t> serialized;
|
|
chunk.SerializeTo(serialized);
|
|
|
|
ASSERT_HAS_VALUE_AND_ASSIGN(ForwardTsnChunk deserialized,
|
|
ForwardTsnChunk::Parse(serialized));
|
|
EXPECT_EQ(*deserialized.new_cumulative_tsn(), 123u);
|
|
EXPECT_THAT(
|
|
deserialized.skipped_streams(),
|
|
ElementsAre(ForwardTsnChunk::SkippedStream(StreamID(1), SSN(23)),
|
|
ForwardTsnChunk::SkippedStream(StreamID(42), SSN(99))));
|
|
|
|
EXPECT_EQ(deserialized.ToString(),
|
|
"FORWARD-TSN, new_cumulative_tsn=123, skip 1:23, skip 42:99");
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace dcsctp
|