Fail RTP parsing on excessive padding length.
BUG=webrtc:4771 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/1220863002 Cr-Commit-Position: refs/heads/master@{#9525}
This commit is contained in:
@@ -402,7 +402,7 @@ TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSetEndingAfterFirstRedHeader) {
|
TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSetEndingAfterFirstRedHeader) {
|
||||||
const uint8_t kPacket[] = {0xa9,
|
const uint8_t kPacket[] = {0x89,
|
||||||
0x27,
|
0x27,
|
||||||
0x3a,
|
0x3a,
|
||||||
0x83,
|
0x83,
|
||||||
|
|||||||
@@ -237,7 +237,8 @@ bool RTPPayloadRegistry::RestoreOriginalPacket(uint8_t** restored_packet,
|
|||||||
size_t* packet_length,
|
size_t* packet_length,
|
||||||
uint32_t original_ssrc,
|
uint32_t original_ssrc,
|
||||||
const RTPHeader& header) const {
|
const RTPHeader& header) const {
|
||||||
if (kRtxHeaderSize + header.headerLength > *packet_length) {
|
if (kRtxHeaderSize + header.headerLength + header.paddingLength >
|
||||||
|
*packet_length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const uint8_t* rtx_header = packet + header.headerLength;
|
const uint8_t* rtx_header = packet + header.headerLength;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
|
#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
|
#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
|
||||||
@@ -60,6 +61,7 @@ int32_t RTPReceiverVideo::ParseRtpPacket(WebRtcRTPHeader* rtp_header,
|
|||||||
rtp_header->header.timestamp);
|
rtp_header->header.timestamp);
|
||||||
rtp_header->type.Video.codec = specific_payload.Video.videoCodecType;
|
rtp_header->type.Video.codec = specific_payload.Video.videoCodecType;
|
||||||
|
|
||||||
|
DCHECK_GE(payload_length, rtp_header->header.paddingLength);
|
||||||
const size_t payload_data_length =
|
const size_t payload_data_length =
|
||||||
payload_length - rtp_header->header.paddingLength;
|
payload_length - rtp_header->header.paddingLength;
|
||||||
|
|
||||||
|
|||||||
@@ -770,8 +770,10 @@ TEST_F(RtpSenderTest, SendPadding) {
|
|||||||
EXPECT_EQ(kMaxPaddingLength + rtp_header_len,
|
EXPECT_EQ(kMaxPaddingLength + rtp_header_len,
|
||||||
transport_.last_sent_packet_len_);
|
transport_.last_sent_packet_len_);
|
||||||
// Parse sent packet.
|
// Parse sent packet.
|
||||||
ASSERT_TRUE(rtp_parser->Parse(transport_.last_sent_packet_, kPaddingBytes,
|
ASSERT_TRUE(rtp_parser->Parse(transport_.last_sent_packet_,
|
||||||
|
transport_.last_sent_packet_len_,
|
||||||
&rtp_header));
|
&rtp_header));
|
||||||
|
EXPECT_EQ(kMaxPaddingLength, rtp_header.paddingLength);
|
||||||
|
|
||||||
// Verify sequence number and timestamp.
|
// Verify sequence number and timestamp.
|
||||||
EXPECT_EQ(seq_num++, rtp_header.sequenceNumber);
|
EXPECT_EQ(seq_num++, rtp_header.sequenceNumber);
|
||||||
|
|||||||
@@ -355,6 +355,8 @@ bool RtpHeaderParser::Parse(RTPHeader& header,
|
|||||||
}
|
}
|
||||||
header.headerLength += XLen;
|
header.headerLength += XLen;
|
||||||
}
|
}
|
||||||
|
if (header.headerLength + header.paddingLength > static_cast<size_t>(length))
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,9 @@ bool StreamObserver::SendRtp(const uint8_t* packet, size_t length) {
|
|||||||
++total_packets_sent_;
|
++total_packets_sent_;
|
||||||
if (header.paddingLength > 0)
|
if (header.paddingLength > 0)
|
||||||
++padding_packets_sent_;
|
++padding_packets_sent_;
|
||||||
if (rtx_media_ssrcs_.find(header.ssrc) != rtx_media_ssrcs_.end()) {
|
// Handle RTX retransmission, but only for non-padding-only packets.
|
||||||
|
if (rtx_media_ssrcs_.find(header.ssrc) != rtx_media_ssrcs_.end() &&
|
||||||
|
header.headerLength + header.paddingLength != length) {
|
||||||
rtx_media_sent_ += length - header.headerLength - header.paddingLength;
|
rtx_media_sent_ += length - header.headerLength - header.paddingLength;
|
||||||
if (header.paddingLength == 0)
|
if (header.paddingLength == 0)
|
||||||
++rtx_media_packets_sent_;
|
++rtx_media_packets_sent_;
|
||||||
@@ -141,9 +143,8 @@ bool StreamObserver::SendRtp(const uint8_t* packet, size_t length) {
|
|||||||
EXPECT_TRUE(payload_registry_->RestoreOriginalPacket(
|
EXPECT_TRUE(payload_registry_->RestoreOriginalPacket(
|
||||||
&restored_packet_ptr, packet, &restored_length,
|
&restored_packet_ptr, packet, &restored_length,
|
||||||
rtx_media_ssrcs_[header.ssrc], header));
|
rtx_media_ssrcs_[header.ssrc], header));
|
||||||
length = restored_length;
|
EXPECT_TRUE(
|
||||||
EXPECT_TRUE(rtp_parser_->Parse(
|
rtp_parser_->Parse(restored_packet_ptr, restored_length, &header));
|
||||||
restored_packet, static_cast<int>(length), &header));
|
|
||||||
} else {
|
} else {
|
||||||
rtp_rtcp_->SetRemoteSSRC(header.ssrc);
|
rtp_rtcp_->SetRemoteSSRC(header.ssrc);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user