From 2e43b26c78f465d71dfd180d55d04be1b8d4f1fb Mon Sep 17 00:00:00 2001 From: pbos Date: Tue, 30 Jun 2015 01:32:40 -0700 Subject: [PATCH] Prevent OOB reads in FEC packets without complete RED headers. BUG=webrtc:4771 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/1220753003 Cr-Commit-Position: refs/heads/master@{#9518} --- .../rtp_rtcp/source/fec_receiver_impl.cc | 6 +- .../rtp_rtcp/source/fec_receiver_unittest.cc | 94 +++++++++++++++++++ 2 files changed, 98 insertions(+), 2 deletions(-) diff --git a/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc b/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc index ce240860a5..cf46ca9c33 100644 --- a/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc @@ -104,7 +104,7 @@ int32_t FecReceiverImpl::AddReceivedRedPacket( if (incoming_rtp_packet[header.headerLength] & 0x80) { // f bit set in RED header REDHeaderLength = 4; - if (payload_data_length < REDHeaderLength) { + if (payload_data_length < REDHeaderLength + 1u) { LOG(LS_WARNING) << "Corrupt/truncated FEC packet."; return -1; } @@ -128,7 +128,9 @@ int32_t FecReceiverImpl::AddReceivedRedPacket( LOG(LS_WARNING) << "More than 2 blocks in packet not supported."; return -1; } - if (blockLength > payload_data_length - REDHeaderLength) { + // Check that the packet is long enough to contain data in the following + // block. + if (blockLength > payload_data_length - (REDHeaderLength + 1)) { LOG(LS_WARNING) << "Block length longer than packet."; return -1; } diff --git a/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc index 3cd2a9e462..cc5d65c975 100644 --- a/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc @@ -401,4 +401,98 @@ TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSet) { SurvivesMaliciousPacket(kTruncatedPacket, sizeof(kTruncatedPacket), 100); } +TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSetEndingAfterFirstRedHeader) { + const uint8_t kPacket[] = {0xa9, + 0x27, + 0x3a, + 0x83, + 0x27, + 0x3a, + 0x3a, + 0xf3, + 0x67, + 0xbe, + 0x2a, + 0xa9, + 0x27, + 0x54, + 0x3a, + 0x3a, + 0x2a, + 0x67, + 0x3a, + 0xf3, + 0x67, + 0xbe, + 0x2a, + 0x27, + 0xe6, + 0xf6, + 0x03, + 0x3e, + 0x29, + 0x27, + 0x21, + 0x27, + 0x2a, + 0x29, + 0x21, + 0x4b, + 0x29, + 0x3a, + 0x28, + 0x29, + 0xbf, + 0x29, + 0x2a, + 0x26, + 0x29, + 0xae, + 0x27, + 0xa6, + 0xf6, + 0x00, + 0x03, + 0x3e}; + SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); +} + +TEST_F(ReceiverFecTest, TruncatedPacketWithoutDataPastFirstBlock) { + const uint8_t kPacket[] = {0x82, + 0x38, + 0x92, + 0x38, + 0x92, + 0x38, + 0xde, + 0x2a, + 0x11, + 0xc8, + 0xa3, + 0xc4, + 0x82, + 0x38, + 0x2a, + 0x21, + 0x2a, + 0x28, + 0x92, + 0x38, + 0x92, + 0x00, + 0x00, + 0x0a, + 0x3a, + 0xc8, + 0xa3, + 0x3a, + 0x27, + 0xc4, + 0x2a, + 0x21, + 0x2a, + 0x28}; + SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); +} + } // namespace webrtc