system/bt
リビジョン | 8dee3a482dd0e75d31a1b7857d5e5d9d8ca55b49 (tree) |
---|---|
日時 | 2018-11-06 06:52:57 |
作者 | Ugo Yu <ugoyu@goog...> |
コミッター | Rohit Yengisetty |
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 ad4098c340b52acdb0f48fd3e2612d810e71f4c4)
@@ -23,6 +23,7 @@ | ||
23 | 23 | * |
24 | 24 | ******************************************************************************/ |
25 | 25 | |
26 | +#include <cutils/log.h> | |
26 | 27 | #include <string.h> |
27 | 28 | #include "bt_types.h" |
28 | 29 | #include "bt_target.h" |
@@ -256,10 +257,15 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) | ||
256 | 257 | UINT16 offset; |
257 | 258 | UINT16 ex_len; |
258 | 259 | UINT8 pad_len = 0; |
260 | + UINT16 len; | |
259 | 261 | |
262 | + len = p_data->p_pkt->len; | |
260 | 263 | p = p_start = (UINT8 *)(p_data->p_pkt + 1) + p_data->p_pkt->offset; |
261 | 264 | |
262 | 265 | /* parse media packet header */ |
266 | + offset = 12; | |
267 | + // AVDT_MSG_PRS_OCTET1(1) + AVDT_MSG_PRS_M_PT(1) + UINT16(2) + UINT32(4) + 4 | |
268 | + if (offset > len) goto length_error; | |
263 | 269 | AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc); |
264 | 270 | AVDT_MSG_PRS_M_PT(p, m_pt, marker); |
265 | 271 | BE_STREAM_TO_UINT16(seq, p); |
@@ -269,19 +275,20 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) | ||
269 | 275 | UNUSED(o_v); |
270 | 276 | |
271 | 277 | /* skip over any csrc's in packet */ |
278 | + offset += o_cc * 4; | |
272 | 279 | p += o_cc * 4; |
273 | 280 | |
274 | 281 | /* check for and skip over extension header */ |
275 | 282 | if (o_x) |
276 | 283 | { |
284 | + offset += 4; | |
285 | + if (offset > len) goto length_error; | |
277 | 286 | p += 2; |
278 | 287 | BE_STREAM_TO_UINT16(ex_len, p); |
288 | + offset += ex_len * 4; | |
279 | 289 | p += ex_len * 4; |
280 | 290 | } |
281 | 291 | |
282 | - /* save our new offset */ | |
283 | - offset = (UINT16) (p - p_start); | |
284 | - | |
285 | 292 | /* adjust length for any padding at end of packet */ |
286 | 293 | if (o_p) |
287 | 294 | { |
@@ -325,6 +332,12 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) | ||
325 | 332 | osi_free_and_reset((void **)&p_data->p_pkt); |
326 | 333 | } |
327 | 334 | } |
335 | + return; | |
336 | +length_error: | |
337 | + android_errorWriteLog(0x534e4554, "111450156"); | |
338 | + AVDT_TRACE_WARNING("%s: hdl packet length %d too short: must be at least %d", | |
339 | + __func__, len, offset); | |
340 | + osi_free_and_reset((void**)&p_data->p_pkt); | |
328 | 341 | } |
329 | 342 | |
330 | 343 | #if AVDT_REPORTING == TRUE |
@@ -343,6 +356,7 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) | ||
343 | 356 | UINT8 *p_start = p; |
344 | 357 | UINT32 ssrc; |
345 | 358 | UINT8 o_v, o_p, o_cc; |
359 | + UINT16 min_len = 0; | |
346 | 360 | AVDT_REPORT_TYPE pt; |
347 | 361 | tAVDT_REPORT_DATA report, *p_rpt; |
348 | 362 |
@@ -351,6 +365,14 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) | ||
351 | 365 | { |
352 | 366 | p_rpt = &report; |
353 | 367 | /* parse report packet header */ |
368 | + min_len += 8; | |
369 | + if (min_len > len) { | |
370 | + android_errorWriteLog(0x534e4554, "111450156"); | |
371 | + AVDT_TRACE_WARNING( | |
372 | + "%s: hdl packet length %d too short: must be at least %d", __func__, | |
373 | + len, min_len); | |
374 | + goto avdt_scb_hdl_report_exit; | |
375 | + } | |
354 | 376 | AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc); |
355 | 377 | pt = *p++; |
356 | 378 | p += 2; |
@@ -362,6 +384,14 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) | ||
362 | 384 | switch(pt) |
363 | 385 | { |
364 | 386 | case AVDT_RTCP_PT_SR: /* the packet type - SR (Sender Report) */ |
387 | + min_len += 20; | |
388 | + if (min_len > len) { | |
389 | + android_errorWriteLog(0x534e4554, "111450156"); | |
390 | + AVDT_TRACE_WARNING( | |
391 | + "%s: hdl packet length %d too short: must be at least %d", | |
392 | + __func__, len, min_len); | |
393 | + goto avdt_scb_hdl_report_exit; | |
394 | + } | |
365 | 395 | BE_STREAM_TO_UINT32(report.sr.ntp_sec, p); |
366 | 396 | BE_STREAM_TO_UINT32(report.sr.ntp_frac, p); |
367 | 397 | BE_STREAM_TO_UINT32(report.sr.rtp_time, p); |
@@ -370,6 +400,14 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) | ||
370 | 400 | break; |
371 | 401 | |
372 | 402 | case AVDT_RTCP_PT_RR: /* the packet type - RR (Receiver Report) */ |
403 | + min_len += 20; | |
404 | + if (min_len > len) { | |
405 | + android_errorWriteLog(0x534e4554, "111450156"); | |
406 | + AVDT_TRACE_WARNING( | |
407 | + "%s: hdl packet length %d too short: must be at least %d", | |
408 | + __func__, len, min_len); | |
409 | + goto avdt_scb_hdl_report_exit; | |
410 | + } | |
373 | 411 | report.rr.frag_lost = *p; |
374 | 412 | BE_STREAM_TO_UINT32(report.rr.packet_lost, p); |
375 | 413 | report.rr.packet_lost &= 0xFFFFFF; |
@@ -382,10 +420,25 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) | ||
382 | 420 | case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */ |
383 | 421 | if(*p == AVDT_RTCP_SDES_CNAME) |
384 | 422 | { |
423 | + min_len += sizeof(tAVDT_REPORT_DATA) + 2; | |
424 | + if (min_len > len) { | |
425 | + android_errorWriteLog(0x534e4554, "111450156"); | |
426 | + AVDT_TRACE_WARNING( | |
427 | + "%s: hdl packet length %d too short: must be at least %d", | |
428 | + __func__, len, min_len); | |
429 | + goto avdt_scb_hdl_report_exit; | |
430 | + } | |
385 | 431 | p_rpt = (tAVDT_REPORT_DATA *)(p+2); |
386 | 432 | } |
387 | 433 | else |
388 | 434 | { |
435 | + if (min_len + 1 > len) { | |
436 | + android_errorWriteLog(0x534e4554, "111450156"); | |
437 | + AVDT_TRACE_WARNING( | |
438 | + "%s: hdl packet length %d too short: must be at least %d", | |
439 | + __func__, len, min_len + 2); | |
440 | + goto avdt_scb_hdl_report_exit; | |
441 | + } | |
389 | 442 | AVDT_TRACE_WARNING( " - SDES SSRC=0x%08x sc=%d %d len=%d %s", |
390 | 443 | ssrc, o_cc, *p, *(p+1), p+2); |
391 | 444 | result = AVDT_BUSY; |
@@ -401,6 +454,7 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) | ||
401 | 454 | (*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, p_rpt); |
402 | 455 | |
403 | 456 | } |
457 | +avdt_scb_hdl_report_exit: | |
404 | 458 | p_start += len; |
405 | 459 | return p_start; |
406 | 460 | } |