 Chromium Code Reviews
 Chromium Code Reviews Issue 1238033003:
  Prevent OOB reads for truncated H264 STAP-A packets.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 1238033003:
  Prevent OOB reads for truncated H264 STAP-A packets.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| OLD | NEW | 
|---|---|
| 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 Loading... | |
| 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 bool VerifyStapANaluLengths(const uint8_t* nalu_ptr, size_t length_remaining) { | |
| 44 while (length_remaining > 0) { | |
| 
stefan-webrtc
2015/07/28 14:22:18
Add a TODO to not parse this twice (here and in th
 | |
| 45 // Buffer doesn't contain room for additional nalu length. | |
| 46 if (length_remaining < sizeof(uint16_t)) | |
| 47 return false; | |
| 48 uint16_t nalu_size = nalu_ptr[0] << 8 | nalu_ptr[1]; | |
| 49 nalu_ptr += sizeof(uint16_t); | |
| 50 length_remaining -= sizeof(uint16_t); | |
| 51 if (nalu_size > length_remaining) | |
| 52 return false; | |
| 53 nalu_ptr += nalu_size; | |
| 54 length_remaining -= nalu_size; | |
| 55 } | |
| 56 return true; | |
| 57 } | |
| 58 | |
| 43 bool ParseSingleNalu(RtpDepacketizer::ParsedPayload* parsed_payload, | 59 bool ParseSingleNalu(RtpDepacketizer::ParsedPayload* parsed_payload, | 
| 44 const uint8_t* payload_data, | 60 const uint8_t* payload_data, | 
| 45 size_t payload_data_length) { | 61 size_t payload_data_length) { | 
| 46 parsed_payload->type.Video.width = 0; | 62 parsed_payload->type.Video.width = 0; | 
| 47 parsed_payload->type.Video.height = 0; | 63 parsed_payload->type.Video.height = 0; | 
| 48 parsed_payload->type.Video.codec = kRtpVideoH264; | 64 parsed_payload->type.Video.codec = kRtpVideoH264; | 
| 49 parsed_payload->type.Video.isFirstPacket = true; | 65 parsed_payload->type.Video.isFirstPacket = true; | 
| 50 RTPVideoHeaderH264* h264_header = | 66 RTPVideoHeaderH264* h264_header = | 
| 51 &parsed_payload->type.Video.codecHeader.H264; | 67 &parsed_payload->type.Video.codecHeader.H264; | 
| 52 | 68 | 
| 53 const uint8_t* nalu_start = payload_data + kNalHeaderSize; | 69 const uint8_t* nalu_start = payload_data + kNalHeaderSize; | 
| 54 size_t nalu_length = payload_data_length - kNalHeaderSize; | 70 size_t nalu_length = payload_data_length - kNalHeaderSize; | 
| 55 uint8_t nal_type = payload_data[0] & kTypeMask; | 71 uint8_t nal_type = payload_data[0] & kTypeMask; | 
| 56 if (nal_type == kStapA) { | 72 if (nal_type == kStapA) { | 
| 57 // Skip the StapA header (StapA nal type + length). | 73 // Skip the StapA header (StapA nal type + length). | 
| 58 if (payload_data_length <= kStapAHeaderSize) { | 74 if (payload_data_length <= kStapAHeaderSize) { | 
| 59 LOG(LS_ERROR) << "StapA header truncated."; | 75 LOG(LS_ERROR) << "StapA header truncated."; | 
| 60 return false; | 76 return false; | 
| 61 } | 77 } | 
| 78 if (!VerifyStapANaluLengths(nalu_start, nalu_length)) | |
| 
stefan-webrtc
2015/07/28 14:22:19
Log this?
 | |
| 79 return false; | |
| 80 | |
| 62 nal_type = payload_data[kStapAHeaderSize] & kTypeMask; | 81 nal_type = payload_data[kStapAHeaderSize] & kTypeMask; | 
| 63 nalu_start += kStapAHeaderSize; | 82 nalu_start += kStapAHeaderSize; | 
| 64 nalu_length -= kStapAHeaderSize; | 83 nalu_length -= kStapAHeaderSize; | 
| 65 h264_header->packetization_type = kH264StapA; | 84 h264_header->packetization_type = kH264StapA; | 
| 66 } else { | 85 } else { | 
| 67 h264_header->packetization_type = kH264SingleNalu; | 86 h264_header->packetization_type = kH264SingleNalu; | 
| 68 } | 87 } | 
| 69 h264_header->nalu_type = nal_type; | 88 h264_header->nalu_type = nal_type; | 
| 70 | 89 | 
| 71 // We can read resolution out of sps packets. | 90 // We can read resolution out of sps packets. | 
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 345 // will depacketize the STAP-A into NAL units later. | 364 // will depacketize the STAP-A into NAL units later. | 
| 346 if (!ParseSingleNalu(parsed_payload, payload_data, payload_data_length)) | 365 if (!ParseSingleNalu(parsed_payload, payload_data, payload_data_length)) | 
| 347 return false; | 366 return false; | 
| 348 } | 367 } | 
| 349 | 368 | 
| 350 parsed_payload->payload = payload_data + offset; | 369 parsed_payload->payload = payload_data + offset; | 
| 351 parsed_payload->payload_length = payload_data_length - offset; | 370 parsed_payload->payload_length = payload_data_length - offset; | 
| 352 return true; | 371 return true; | 
| 353 } | 372 } | 
| 354 } // namespace webrtc | 373 } // namespace webrtc | 
| OLD | NEW |