From 7ada923a94de3cd95142b3052996f9b38e134f39 Mon Sep 17 00:00:00 2001 From: pbos Date: Tue, 30 Jun 2015 05:09:39 -0700 Subject: [PATCH] Prevent OOB reads for zero-length H264 payloads. Also fixes zero-length OOB reads for generic packetization. BUG=webrtc:4771 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/1218013002 Cr-Commit-Position: refs/heads/master@{#9521} --- webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc | 6 ++++++ .../modules/rtp_rtcp/source/rtp_format_h264_unittest.cc | 8 ++++++++ .../modules/rtp_rtcp/source/rtp_format_video_generic.cc | 5 +++++ 3 files changed, 19 insertions(+) diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc index ebd46b02e..a5b42ab3e 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc @@ -10,6 +10,7 @@ #include +#include "webrtc/base/logging.h" #include "webrtc/modules/interface/module_common_types.h" #include "webrtc/modules/rtp_rtcp/source/byte_io.h" #include "webrtc/modules/rtp_rtcp/source/h264_sps_parser.h" @@ -316,6 +317,11 @@ bool RtpDepacketizerH264::Parse(ParsedPayload* parsed_payload, const uint8_t* payload_data, size_t payload_data_length) { assert(parsed_payload != NULL); + if (payload_data_length == 0) { + LOG(LS_ERROR) << "Empty payload."; + return false; + } + uint8_t nal_type = payload_data[0] & kTypeMask; size_t offset = 0; if (nal_type == kFuA) { diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc index 66a19ddf5..8fa83010f 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc @@ -537,4 +537,12 @@ TEST_F(RtpDepacketizerH264Test, TestFuA) { EXPECT_EQ(kH264FuA, payload.type.Video.codecHeader.H264.packetization_type); EXPECT_EQ(kIdr, payload.type.Video.codecHeader.H264.nalu_type); } + +TEST_F(RtpDepacketizerH264Test, TestEmptyPayload) { + // Using a wild pointer to crash on accesses from inside the depacketizer. + uint8_t* garbage_ptr = reinterpret_cast(0x4711); + RtpDepacketizer::ParsedPayload payload; + EXPECT_FALSE(depacketizer_->Parse(&payload, garbage_ptr, 0)); +} + } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc index 1fa288aca..39b64c6ff 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc @@ -10,6 +10,7 @@ #include +#include "webrtc/base/logging.h" #include "webrtc/modules/interface/module_common_types.h" #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" @@ -90,6 +91,10 @@ bool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload, const uint8_t* payload_data, size_t payload_data_length) { assert(parsed_payload != NULL); + if (payload_data_length == 0) { + LOG(LS_ERROR) << "Empty payload."; + return false; + } uint8_t generic_header = *payload_data++; --payload_data_length;