Chromium Code Reviews

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

Issue 1219703002: Prevent out-of-bounds reads for short FEC packets. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « no previous file | webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.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) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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 63 matching lines...)
74 // block length: 10 bits Length in bytes of the corresponding data 74 // block length: 10 bits Length in bytes of the corresponding data
75 // block excluding header. 75 // block excluding header.
76 76
77 int32_t FecReceiverImpl::AddReceivedRedPacket( 77 int32_t FecReceiverImpl::AddReceivedRedPacket(
78 const RTPHeader& header, const uint8_t* incoming_rtp_packet, 78 const RTPHeader& header, const uint8_t* incoming_rtp_packet,
79 size_t packet_length, uint8_t ulpfec_payload_type) { 79 size_t packet_length, uint8_t ulpfec_payload_type) {
80 CriticalSectionScoped cs(crit_sect_.get()); 80 CriticalSectionScoped cs(crit_sect_.get());
81 uint8_t REDHeaderLength = 1; 81 uint8_t REDHeaderLength = 1;
82 size_t payload_data_length = packet_length - header.headerLength; 82 size_t payload_data_length = packet_length - header.headerLength;
83 83
84 if (payload_data_length == 0) {
85 LOG(LS_WARNING) << "Corrupt/truncated FEC packet.";
86 return -1;
87 }
88
84 // Add to list without RED header, aka a virtual RTP packet 89 // Add to list without RED header, aka a virtual RTP packet
85 // we remove the RED header 90 // we remove the RED header
86 91
87 ForwardErrorCorrection::ReceivedPacket* received_packet = 92 ForwardErrorCorrection::ReceivedPacket* received_packet =
stefan-webrtc 2015/06/29 13:19:50 Can you switch this to a scoped_ptr?
pbos-webrtc 2015/06/29 13:30:07 Done.
88 new ForwardErrorCorrection::ReceivedPacket; 93 new ForwardErrorCorrection::ReceivedPacket;
89 received_packet->pkt = new ForwardErrorCorrection::Packet; 94 received_packet->pkt = new ForwardErrorCorrection::Packet;
stefan-webrtc 2015/06/29 13:19:50 Doesn't this require deletion at line 109, 123 and
pbos-webrtc 2015/06/29 13:30:08 No, deleted in ~ReceivedPacket.
90 95
91 // get payload type from RED header 96 // get payload type from RED header
92 uint8_t payload_type = 97 uint8_t payload_type =
93 incoming_rtp_packet[header.headerLength] & 0x7f; 98 incoming_rtp_packet[header.headerLength] & 0x7f;
94 99
95 received_packet->is_fec = payload_type == ulpfec_payload_type; 100 received_packet->is_fec = payload_type == ulpfec_payload_type;
96 received_packet->seq_num = header.sequenceNumber; 101 received_packet->seq_num = header.sequenceNumber;
97 102
98 uint16_t blockLength = 0; 103 uint16_t blockLength = 0;
99 if (incoming_rtp_packet[header.headerLength] & 0x80) { 104 if (incoming_rtp_packet[header.headerLength] & 0x80) {
100 // f bit set in RED header 105 // f bit set in RED header
101 REDHeaderLength = 4; 106 REDHeaderLength = 4;
107 if (payload_data_length < REDHeaderLength) {
108 LOG(LS_WARNING) << "Corrupt/truncated FEC packet.";
109 delete received_packet;
110 return -1;
111 }
112
102 uint16_t timestamp_offset = 113 uint16_t timestamp_offset =
103 (incoming_rtp_packet[header.headerLength + 1]) << 8; 114 (incoming_rtp_packet[header.headerLength + 1]) << 8;
104 timestamp_offset += 115 timestamp_offset +=
105 incoming_rtp_packet[header.headerLength + 2]; 116 incoming_rtp_packet[header.headerLength + 2];
106 timestamp_offset = timestamp_offset >> 2; 117 timestamp_offset = timestamp_offset >> 2;
107 if (timestamp_offset != 0) { 118 if (timestamp_offset != 0) {
108 // |timestampOffset| should be 0. However, it's possible this is the first
109 // location a corrupt payload can be caught, so don't assert.
110 LOG(LS_WARNING) << "Corrupt payload found."; 119 LOG(LS_WARNING) << "Corrupt payload found.";
111 delete received_packet; 120 delete received_packet;
112 return -1; 121 return -1;
113 } 122 }
114 123
115 blockLength = 124 blockLength =
116 (0x03 & incoming_rtp_packet[header.headerLength + 2]) << 8; 125 (0x03 & incoming_rtp_packet[header.headerLength + 2]) << 8;
117 blockLength += (incoming_rtp_packet[header.headerLength + 3]); 126 blockLength += (incoming_rtp_packet[header.headerLength + 3]);
118 127
119 // check next RED header 128 // check next RED header
120 if (incoming_rtp_packet[header.headerLength + 4] & 0x80) { 129 if (incoming_rtp_packet[header.headerLength + 4] & 0x80) {
121 // more than 2 blocks in packet not supported 130 LOG(LS_WARNING) << "More than 2 blocks in packet not supported.";
122 delete received_packet; 131 delete received_packet;
123 assert(false);
124 return -1; 132 return -1;
125 } 133 }
126 if (blockLength > payload_data_length - REDHeaderLength) { 134 if (blockLength > payload_data_length - REDHeaderLength) {
127 // block length longer than packet 135 LOG(LS_WARNING) << "Block length longer than packet.";
128 delete received_packet; 136 delete received_packet;
129 assert(false);
130 return -1; 137 return -1;
131 } 138 }
132 } 139 }
133 ++packet_counter_.num_packets; 140 ++packet_counter_.num_packets;
134 141
135 ForwardErrorCorrection::ReceivedPacket* second_received_packet = NULL; 142 ForwardErrorCorrection::ReceivedPacket* second_received_packet = NULL;
136 if (blockLength > 0) { 143 if (blockLength > 0) {
137 // handle block length, split into 2 packets 144 // handle block length, split into 2 packets
138 REDHeaderLength = 5; 145 REDHeaderLength = 5;
139 146
(...skipping 108 matching lines...)
248 return -1; 255 return -1;
249 } 256 }
250 crit_sect_->Enter(); 257 crit_sect_->Enter();
251 (*it)->returned = true; 258 (*it)->returned = true;
252 } 259 }
253 crit_sect_->Leave(); 260 crit_sect_->Leave();
254 return 0; 261 return 0;
255 } 262 }
256 263
257 } // namespace webrtc 264 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine