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

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: feedback Created 5 years, 5 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/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...) Expand 10 before | Expand all | Expand 10 after
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 rtc::scoped_ptr<ForwardErrorCorrection::ReceivedPacket> received_packet(
88 new ForwardErrorCorrection::ReceivedPacket; 93 new ForwardErrorCorrection::ReceivedPacket);
89 received_packet->pkt = new ForwardErrorCorrection::Packet; 94 received_packet->pkt = new ForwardErrorCorrection::Packet;
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 return -1;
110 }
111
102 uint16_t timestamp_offset = 112 uint16_t timestamp_offset =
103 (incoming_rtp_packet[header.headerLength + 1]) << 8; 113 (incoming_rtp_packet[header.headerLength + 1]) << 8;
104 timestamp_offset += 114 timestamp_offset +=
105 incoming_rtp_packet[header.headerLength + 2]; 115 incoming_rtp_packet[header.headerLength + 2];
106 timestamp_offset = timestamp_offset >> 2; 116 timestamp_offset = timestamp_offset >> 2;
107 if (timestamp_offset != 0) { 117 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."; 118 LOG(LS_WARNING) << "Corrupt payload found.";
111 delete received_packet;
112 return -1; 119 return -1;
113 } 120 }
114 121
115 blockLength = 122 blockLength =
116 (0x03 & incoming_rtp_packet[header.headerLength + 2]) << 8; 123 (0x03 & incoming_rtp_packet[header.headerLength + 2]) << 8;
117 blockLength += (incoming_rtp_packet[header.headerLength + 3]); 124 blockLength += (incoming_rtp_packet[header.headerLength + 3]);
118 125
119 // check next RED header 126 // check next RED header
120 if (incoming_rtp_packet[header.headerLength + 4] & 0x80) { 127 if (incoming_rtp_packet[header.headerLength + 4] & 0x80) {
121 // more than 2 blocks in packet not supported 128 LOG(LS_WARNING) << "More than 2 blocks in packet not supported.";
122 delete received_packet;
123 assert(false);
124 return -1; 129 return -1;
125 } 130 }
126 if (blockLength > payload_data_length - REDHeaderLength) { 131 if (blockLength > payload_data_length - REDHeaderLength) {
127 // block length longer than packet 132 LOG(LS_WARNING) << "Block length longer than packet.";
128 delete received_packet;
129 assert(false);
130 return -1; 133 return -1;
131 } 134 }
132 } 135 }
133 ++packet_counter_.num_packets; 136 ++packet_counter_.num_packets;
134 137
135 ForwardErrorCorrection::ReceivedPacket* second_received_packet = NULL; 138 rtc::scoped_ptr<ForwardErrorCorrection::ReceivedPacket>
139 second_received_packet;
stefan-webrtc 2015/06/29 13:33:21 Is this guaranteed to be null if you call release(
pbos-webrtc 2015/06/29 13:34:03 This is default-constructed to nullptr.
136 if (blockLength > 0) { 140 if (blockLength > 0) {
137 // handle block length, split into 2 packets 141 // handle block length, split into 2 packets
138 REDHeaderLength = 5; 142 REDHeaderLength = 5;
139 143
140 // copy the RTP header 144 // copy the RTP header
141 memcpy(received_packet->pkt->data, incoming_rtp_packet, 145 memcpy(received_packet->pkt->data, incoming_rtp_packet,
142 header.headerLength); 146 header.headerLength);
143 147
144 // replace the RED payload type 148 // replace the RED payload type
145 received_packet->pkt->data[1] &= 0x80; // reset the payload 149 received_packet->pkt->data[1] &= 0x80; // reset the payload
146 received_packet->pkt->data[1] += 150 received_packet->pkt->data[1] +=
147 payload_type; // set the media payload type 151 payload_type; // set the media payload type
148 152
149 // copy the payload data 153 // copy the payload data
150 memcpy( 154 memcpy(
151 received_packet->pkt->data + header.headerLength, 155 received_packet->pkt->data + header.headerLength,
152 incoming_rtp_packet + header.headerLength + REDHeaderLength, 156 incoming_rtp_packet + header.headerLength + REDHeaderLength,
153 blockLength); 157 blockLength);
154 158
155 received_packet->pkt->length = blockLength; 159 received_packet->pkt->length = blockLength;
156 160
157 second_received_packet = new ForwardErrorCorrection::ReceivedPacket; 161 second_received_packet.reset(new ForwardErrorCorrection::ReceivedPacket);
158 second_received_packet->pkt = new ForwardErrorCorrection::Packet; 162 second_received_packet->pkt = new ForwardErrorCorrection::Packet;
159 163
160 second_received_packet->is_fec = true; 164 second_received_packet->is_fec = true;
161 second_received_packet->seq_num = header.sequenceNumber; 165 second_received_packet->seq_num = header.sequenceNumber;
162 ++packet_counter_.num_fec_packets; 166 ++packet_counter_.num_fec_packets;
163 167
164 // copy the FEC payload data 168 // copy the FEC payload data
165 memcpy(second_received_packet->pkt->data, 169 memcpy(second_received_packet->pkt->data,
166 incoming_rtp_packet + header.headerLength + 170 incoming_rtp_packet + header.headerLength +
167 REDHeaderLength + blockLength, 171 REDHeaderLength + blockLength,
(...skipping 27 matching lines...) Expand all
195 memcpy( 199 memcpy(
196 received_packet->pkt->data + header.headerLength, 200 received_packet->pkt->data + header.headerLength,
197 incoming_rtp_packet + header.headerLength + REDHeaderLength, 201 incoming_rtp_packet + header.headerLength + REDHeaderLength,
198 payload_data_length - REDHeaderLength); 202 payload_data_length - REDHeaderLength);
199 203
200 received_packet->pkt->length = 204 received_packet->pkt->length =
201 header.headerLength + payload_data_length - REDHeaderLength; 205 header.headerLength + payload_data_length - REDHeaderLength;
202 } 206 }
203 207
204 if (received_packet->pkt->length == 0) { 208 if (received_packet->pkt->length == 0) {
205 delete second_received_packet;
206 delete received_packet;
207 return 0; 209 return 0;
208 } 210 }
209 211
210 received_packet_list_.push_back(received_packet); 212 received_packet_list_.push_back(received_packet.release());
211 if (second_received_packet) { 213 if (second_received_packet) {
212 received_packet_list_.push_back(second_received_packet); 214 received_packet_list_.push_back(second_received_packet.release());
213 } 215 }
214 return 0; 216 return 0;
215 } 217 }
216 218
217 int32_t FecReceiverImpl::ProcessReceivedFec() { 219 int32_t FecReceiverImpl::ProcessReceivedFec() {
218 crit_sect_->Enter(); 220 crit_sect_->Enter();
219 if (!received_packet_list_.empty()) { 221 if (!received_packet_list_.empty()) {
220 // Send received media packet to VCM. 222 // Send received media packet to VCM.
221 if (!received_packet_list_.front()->is_fec) { 223 if (!received_packet_list_.front()->is_fec) {
222 ForwardErrorCorrection::Packet* packet = 224 ForwardErrorCorrection::Packet* packet =
(...skipping 25 matching lines...) Expand all
248 return -1; 250 return -1;
249 } 251 }
250 crit_sect_->Enter(); 252 crit_sect_->Enter();
251 (*it)->returned = true; 253 (*it)->returned = true;
252 } 254 }
253 crit_sect_->Leave(); 255 crit_sect_->Leave();
254 return 0; 256 return 0;
255 } 257 }
256 258
257 } // namespace webrtc 259 } // 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
This is Rietveld 408576698