system/bt
Revision | 369d68ff92cb2915db765eace9daa8c5eb551861 (tree) |
---|---|
Zeit | 2018-11-27 02:19:44 |
Autor | Ugo Yu <ugoyu@goog...> |
Commiter | android-build-team Robot |
DO NOT MERGE: Fix possible OOB when AVDT data channel recive ACL data
Bug: 111450156
Change-Id: Id23eeedcb7bde5866cd53a2f7f1c30f27c5352f6
(cherry picked from commit b0125caafec2183d73fc899ce5a8aee43a6e54af)
(cherry picked from commit f349ff0c65523437b3f20ef54a7b0e5fd56364dc)
@@ -23,6 +23,7 @@ | ||
23 | 23 | * |
24 | 24 | ******************************************************************************/ |
25 | 25 | |
26 | +#include <cutils/log.h> | |
26 | 27 | #include <string.h> |
27 | 28 | #include "a2dp_codec_api.h" |
28 | 29 | #include "avdt_api.h" |
@@ -231,10 +232,14 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) { | ||
231 | 232 | uint16_t offset; |
232 | 233 | uint16_t ex_len; |
233 | 234 | uint8_t pad_len = 0; |
235 | + uint16_t len = p_data->p_pkt->len; | |
234 | 236 | |
235 | 237 | p = p_start = (uint8_t*)(p_data->p_pkt + 1) + p_data->p_pkt->offset; |
236 | 238 | |
237 | 239 | /* parse media packet header */ |
240 | + offset = 12; | |
241 | + // AVDT_MSG_PRS_OCTET1(1) + AVDT_MSG_PRS_M_PT(1) + UINT16(2) + UINT32(4) + 4 | |
242 | + if (offset > len) goto length_error; | |
238 | 243 | AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc); |
239 | 244 | AVDT_MSG_PRS_M_PT(p, m_pt, marker); |
240 | 245 | BE_STREAM_TO_UINT16(seq, p); |
@@ -242,18 +247,19 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) { | ||
242 | 247 | p += 4; |
243 | 248 | |
244 | 249 | /* skip over any csrc's in packet */ |
250 | + offset += o_cc * 4; | |
245 | 251 | p += o_cc * 4; |
246 | 252 | |
247 | 253 | /* check for and skip over extension header */ |
248 | 254 | if (o_x) { |
255 | + offset += 4; | |
256 | + if (offset > len) goto length_error; | |
249 | 257 | p += 2; |
250 | 258 | BE_STREAM_TO_UINT16(ex_len, p); |
259 | + offset += ex_len * 4; | |
251 | 260 | p += ex_len * 4; |
252 | 261 | } |
253 | 262 | |
254 | - /* save our new offset */ | |
255 | - offset = (uint16_t)(p - p_start); | |
256 | - | |
257 | 263 | /* adjust length for any padding at end of packet */ |
258 | 264 | if (o_p) { |
259 | 265 | /* padding length in last byte of packet */ |
@@ -281,6 +287,12 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) { | ||
281 | 287 | osi_free_and_reset((void**)&p_data->p_pkt); |
282 | 288 | } |
283 | 289 | } |
290 | + return; | |
291 | +length_error: | |
292 | + android_errorWriteLog(0x534e4554, "111450156"); | |
293 | + AVDT_TRACE_WARNING("%s: hdl packet length %d too short: must be at least %d", | |
294 | + __func__, len, offset); | |
295 | + osi_free_and_reset((void**)&p_data->p_pkt); | |
284 | 296 | } |
285 | 297 | |
286 | 298 | #if (AVDT_REPORTING == TRUE) |
@@ -298,12 +310,21 @@ uint8_t* avdt_scb_hdl_report(tAVDT_SCB* p_scb, uint8_t* p, uint16_t len) { | ||
298 | 310 | uint8_t* p_start = p; |
299 | 311 | uint32_t ssrc; |
300 | 312 | uint8_t o_v, o_p, o_cc; |
313 | + uint16_t min_len = 0; | |
301 | 314 | AVDT_REPORT_TYPE pt; |
302 | 315 | tAVDT_REPORT_DATA report; |
303 | 316 | |
304 | 317 | AVDT_TRACE_DEBUG("%s", __func__); |
305 | 318 | if (p_scb->cs.p_report_cback) { |
306 | 319 | /* parse report packet header */ |
320 | + min_len += 8; | |
321 | + if (min_len > len) { | |
322 | + android_errorWriteLog(0x534e4554, "111450156"); | |
323 | + AVDT_TRACE_WARNING( | |
324 | + "%s: hdl packet length %d too short: must be at least %d", __func__, | |
325 | + len, min_len); | |
326 | + goto avdt_scb_hdl_report_exit; | |
327 | + } | |
307 | 328 | AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc); |
308 | 329 | pt = *p++; |
309 | 330 | p += 2; |
@@ -311,6 +332,14 @@ uint8_t* avdt_scb_hdl_report(tAVDT_SCB* p_scb, uint8_t* p, uint16_t len) { | ||
311 | 332 | |
312 | 333 | switch (pt) { |
313 | 334 | case AVDT_RTCP_PT_SR: /* the packet type - SR (Sender Report) */ |
335 | + min_len += 20; | |
336 | + if (min_len > len) { | |
337 | + android_errorWriteLog(0x534e4554, "111450156"); | |
338 | + AVDT_TRACE_WARNING( | |
339 | + "%s: hdl packet length %d too short: must be at least %d", | |
340 | + __func__, len, min_len); | |
341 | + goto avdt_scb_hdl_report_exit; | |
342 | + } | |
314 | 343 | BE_STREAM_TO_UINT32(report.sr.ntp_sec, p); |
315 | 344 | BE_STREAM_TO_UINT32(report.sr.ntp_frac, p); |
316 | 345 | BE_STREAM_TO_UINT32(report.sr.rtp_time, p); |
@@ -319,6 +348,14 @@ uint8_t* avdt_scb_hdl_report(tAVDT_SCB* p_scb, uint8_t* p, uint16_t len) { | ||
319 | 348 | break; |
320 | 349 | |
321 | 350 | case AVDT_RTCP_PT_RR: /* the packet type - RR (Receiver Report) */ |
351 | + min_len += 20; | |
352 | + if (min_len > len) { | |
353 | + android_errorWriteLog(0x534e4554, "111450156"); | |
354 | + AVDT_TRACE_WARNING( | |
355 | + "%s: hdl packet length %d too short: must be at least %d", | |
356 | + __func__, len, min_len); | |
357 | + goto avdt_scb_hdl_report_exit; | |
358 | + } | |
322 | 359 | report.rr.frag_lost = *p; |
323 | 360 | BE_STREAM_TO_UINT32(report.rr.packet_lost, p); |
324 | 361 | report.rr.packet_lost &= 0xFFFFFF; |
@@ -330,9 +367,25 @@ uint8_t* avdt_scb_hdl_report(tAVDT_SCB* p_scb, uint8_t* p, uint16_t len) { | ||
330 | 367 | |
331 | 368 | case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */ |
332 | 369 | uint8_t sdes_type; |
370 | + min_len += 1; | |
371 | + if (min_len > len) { | |
372 | + android_errorWriteLog(0x534e4554, "111450156"); | |
373 | + AVDT_TRACE_WARNING( | |
374 | + "%s: hdl packet length %d too short: must be at least %d", | |
375 | + __func__, len, min_len); | |
376 | + goto avdt_scb_hdl_report_exit; | |
377 | + } | |
333 | 378 | BE_STREAM_TO_UINT8(sdes_type, p); |
334 | 379 | if (sdes_type == AVDT_RTCP_SDES_CNAME) { |
335 | 380 | uint8_t name_length; |
381 | + min_len += 1; | |
382 | + if (min_len > len) { | |
383 | + android_errorWriteLog(0x534e4554, "111450156"); | |
384 | + AVDT_TRACE_WARNING( | |
385 | + "%s: hdl packet length %d too short: must be at least %d", | |
386 | + __func__, len, min_len); | |
387 | + goto avdt_scb_hdl_report_exit; | |
388 | + } | |
336 | 389 | BE_STREAM_TO_UINT8(name_length, p); |
337 | 390 | if (name_length > len - 2 || name_length > AVDT_MAX_CNAME_SIZE) { |
338 | 391 | result = AVDT_BAD_PARAMS; |
@@ -340,6 +393,13 @@ uint8_t* avdt_scb_hdl_report(tAVDT_SCB* p_scb, uint8_t* p, uint16_t len) { | ||
340 | 393 | BE_STREAM_TO_ARRAY(p, &(report.cname[0]), name_length); |
341 | 394 | } |
342 | 395 | } else { |
396 | + if (min_len + 1 > len) { | |
397 | + android_errorWriteLog(0x534e4554, "111450156"); | |
398 | + AVDT_TRACE_WARNING( | |
399 | + "%s: hdl packet length %d too short: must be at least %d", | |
400 | + __func__, len, min_len + 2); | |
401 | + goto avdt_scb_hdl_report_exit; | |
402 | + } | |
343 | 403 | AVDT_TRACE_WARNING(" - SDES SSRC=0x%08x sc=%d %d len=%d %s", ssrc, |
344 | 404 | o_cc, *p, *(p + 1), p + 2); |
345 | 405 | result = AVDT_BUSY; |
@@ -354,6 +414,7 @@ uint8_t* avdt_scb_hdl_report(tAVDT_SCB* p_scb, uint8_t* p, uint16_t len) { | ||
354 | 414 | if (result == AVDT_SUCCESS) |
355 | 415 | (*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, &report); |
356 | 416 | } |
417 | +avdt_scb_hdl_report_exit: | |
357 | 418 | p_start += len; |
358 | 419 | return p_start; |
359 | 420 | } |