Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(554)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc

Issue 1238033003: Prevent OOB reads for truncated H264 STAP-A packets. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: added logging + todos Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/modules/video_coding/main/source/session_info.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 22 matching lines...) Expand all
33 static const size_t kFuAHeaderSize = 2; 33 static const size_t kFuAHeaderSize = 2;
34 static const size_t kLengthFieldSize = 2; 34 static const size_t kLengthFieldSize = 2;
35 static const size_t kStapAHeaderSize = kNalHeaderSize + kLengthFieldSize; 35 static const size_t kStapAHeaderSize = kNalHeaderSize + kLengthFieldSize;
36 36
37 // Bit masks for FU (A and B) indicators. 37 // Bit masks for FU (A and B) indicators.
38 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F }; 38 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F };
39 39
40 // Bit masks for FU (A and B) headers. 40 // Bit masks for FU (A and B) headers.
41 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 }; 41 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 };
42 42
43 // TODO(pbos): Avoid parsing this here as well as inside the jitter buffer.
44 bool VerifyStapANaluLengths(const uint8_t* nalu_ptr, size_t length_remaining) {
45 while (length_remaining > 0) {
46 // Buffer doesn't contain room for additional nalu length.
47 if (length_remaining < sizeof(uint16_t))
48 return false;
49 uint16_t nalu_size = nalu_ptr[0] << 8 | nalu_ptr[1];
50 nalu_ptr += sizeof(uint16_t);
51 length_remaining -= sizeof(uint16_t);
52 if (nalu_size > length_remaining)
53 return false;
54 nalu_ptr += nalu_size;
55 length_remaining -= nalu_size;
56 }
57 return true;
58 }
59
43 bool ParseSingleNalu(RtpDepacketizer::ParsedPayload* parsed_payload, 60 bool ParseSingleNalu(RtpDepacketizer::ParsedPayload* parsed_payload,
44 const uint8_t* payload_data, 61 const uint8_t* payload_data,
45 size_t payload_data_length) { 62 size_t payload_data_length) {
46 parsed_payload->type.Video.width = 0; 63 parsed_payload->type.Video.width = 0;
47 parsed_payload->type.Video.height = 0; 64 parsed_payload->type.Video.height = 0;
48 parsed_payload->type.Video.codec = kRtpVideoH264; 65 parsed_payload->type.Video.codec = kRtpVideoH264;
49 parsed_payload->type.Video.isFirstPacket = true; 66 parsed_payload->type.Video.isFirstPacket = true;
50 RTPVideoHeaderH264* h264_header = 67 RTPVideoHeaderH264* h264_header =
51 &parsed_payload->type.Video.codecHeader.H264; 68 &parsed_payload->type.Video.codecHeader.H264;
52 69
53 const uint8_t* nalu_start = payload_data + kNalHeaderSize; 70 const uint8_t* nalu_start = payload_data + kNalHeaderSize;
54 size_t nalu_length = payload_data_length - kNalHeaderSize; 71 size_t nalu_length = payload_data_length - kNalHeaderSize;
55 uint8_t nal_type = payload_data[0] & kTypeMask; 72 uint8_t nal_type = payload_data[0] & kTypeMask;
56 if (nal_type == kStapA) { 73 if (nal_type == kStapA) {
57 // Skip the StapA header (StapA nal type + length). 74 // Skip the StapA header (StapA nal type + length).
58 if (payload_data_length <= kStapAHeaderSize) { 75 if (payload_data_length <= kStapAHeaderSize) {
59 LOG(LS_ERROR) << "StapA header truncated."; 76 LOG(LS_ERROR) << "StapA header truncated.";
60 return false; 77 return false;
61 } 78 }
79 if (!VerifyStapANaluLengths(nalu_start, nalu_length)) {
80 LOG(LS_ERROR) << "StapA packet with incorrect NALU packet lengths.";
81 return false;
82 }
83
62 nal_type = payload_data[kStapAHeaderSize] & kTypeMask; 84 nal_type = payload_data[kStapAHeaderSize] & kTypeMask;
63 nalu_start += kStapAHeaderSize; 85 nalu_start += kStapAHeaderSize;
64 nalu_length -= kStapAHeaderSize; 86 nalu_length -= kStapAHeaderSize;
65 h264_header->packetization_type = kH264StapA; 87 h264_header->packetization_type = kH264StapA;
66 } else { 88 } else {
67 h264_header->packetization_type = kH264SingleNalu; 89 h264_header->packetization_type = kH264SingleNalu;
68 } 90 }
69 h264_header->nalu_type = nal_type; 91 h264_header->nalu_type = nal_type;
70 92
71 // We can read resolution out of sps packets. 93 // We can read resolution out of sps packets.
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 // will depacketize the STAP-A into NAL units later. 367 // will depacketize the STAP-A into NAL units later.
346 if (!ParseSingleNalu(parsed_payload, payload_data, payload_data_length)) 368 if (!ParseSingleNalu(parsed_payload, payload_data, payload_data_length))
347 return false; 369 return false;
348 } 370 }
349 371
350 parsed_payload->payload = payload_data + offset; 372 parsed_payload->payload = payload_data + offset;
351 parsed_payload->payload_length = payload_data_length - offset; 373 parsed_payload->payload_length = payload_data_length - offset;
352 return true; 374 return true;
353 } 375 }
354 } // namespace webrtc 376 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/video_coding/main/source/session_info.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698