system/bt
Revisão | 03080247f631e57d76e8412d0b7b3726de6078d9 (tree) |
---|---|
Hora | 2019-05-11 06:18:06 |
Autor | Ted Wang <tedwang@goog...> |
Commiter | hamzeh |
DO NOT MERGE Fix potential OOB read in sdpu_get_len_from_type
Add boundary check in sdpu_get_len_from_type to prevent potential OOB read.
Bug: 117105007
Test: Manul
Merged-In: I3755e13ee0a7e22ffd5f48fca909610a26b09d0a
Change-Id: I3755e13ee0a7e22ffd5f48fca909610a26b09d0a
(cherry picked from commit 08202bdcbe5e6cf826926d0995790fcfa309bca8)
@@ -129,7 +129,11 @@ static BOOLEAN find_uuid_in_seq (UINT8 *p , UINT32 seq_len, UINT8 *p_uuid, | ||
129 | 129 | while (p < p_end) |
130 | 130 | { |
131 | 131 | type = *p++; |
132 | - p = sdpu_get_len_from_type (p, type, &len); | |
132 | + p = sdpu_get_len_from_type(p, p_end, type, &len); | |
133 | + if (p == NULL || (p + len) > p_end) { | |
134 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
135 | + break; | |
136 | + } | |
133 | 137 | type = type >> 3; |
134 | 138 | if (type == UUID_DESC_TYPE) |
135 | 139 | { |
@@ -367,6 +367,7 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset) | ||
367 | 367 | unsigned int cpy_len, rem_len; |
368 | 368 | UINT32 list_len; |
369 | 369 | UINT8 *p; |
370 | + UINT8 *p_end; | |
370 | 371 | UINT8 type; |
371 | 372 | |
372 | 373 | #if (SDP_DEBUG_RAW == TRUE) |
@@ -385,13 +386,18 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset) | ||
385 | 386 | cpy_len = p_ccb->p_db->raw_size - p_ccb->p_db->raw_used; |
386 | 387 | list_len = p_ccb->list_len; |
387 | 388 | p = &p_ccb->rsp_list[0]; |
389 | + p_end = &p_ccb->rsp_list[0] + list_len; | |
388 | 390 | |
389 | 391 | if(offset) |
390 | 392 | { |
391 | 393 | cpy_len -= 1; |
392 | 394 | type = *p++; |
393 | 395 | uint8_t* old_p = p; |
394 | - p = sdpu_get_len_from_type (p, type, &list_len); | |
396 | + p = sdpu_get_len_from_type (p, p_end, type, &list_len); | |
397 | + if (p == NULL || (p + list_len) > p_end) { | |
398 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
399 | + return; | |
400 | + } | |
395 | 401 | if ((int)cpy_len < (p - old_p)) { |
396 | 402 | SDP_TRACE_WARNING("%s: no bytes left for data", __func__); |
397 | 403 | return; |
@@ -740,7 +746,11 @@ static void process_service_search_attr_rsp(tCONN_CB *p_ccb, UINT8 *p_reply, | ||
740 | 746 | SDP_TRACE_WARNING ("SDP - Wrong type: 0x%02x in attr_rsp", type); |
741 | 747 | return; |
742 | 748 | } |
743 | - p = sdpu_get_len_from_type (p, type, &seq_len); | |
749 | + p = sdpu_get_len_from_type (p, p + p_ccb->list_len, type, &seq_len); | |
750 | + if (p == NULL || (p + seq_len) > (p + p_ccb->list_len)) { | |
751 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
752 | + return; | |
753 | + } | |
744 | 754 | |
745 | 755 | p_end = &p_ccb->rsp_list[p_ccb->list_len]; |
746 | 756 |
@@ -789,8 +799,8 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end) | ||
789 | 799 | return (NULL); |
790 | 800 | } |
791 | 801 | |
792 | - p = sdpu_get_len_from_type (p, type, &seq_len); | |
793 | - if ((p + seq_len) > p_msg_end) | |
802 | + p = sdpu_get_len_from_type (p, p_msg_end, type, &seq_len); | |
803 | + if (p == NULL || (p + seq_len) > p_msg_end) | |
794 | 804 | { |
795 | 805 | SDP_TRACE_WARNING ("SDP - Bad len in attr_rsp %d", seq_len); |
796 | 806 | return (NULL); |
@@ -810,7 +820,11 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end) | ||
810 | 820 | { |
811 | 821 | /* First get the attribute ID */ |
812 | 822 | type = *p++; |
813 | - p = sdpu_get_len_from_type (p, type, &attr_len); | |
823 | + p = sdpu_get_len_from_type (p, p_msg_end, type, &attr_len); | |
824 | + if (p == NULL || (p + attr_len) > p_seq_end) { | |
825 | + SDP_TRACE_WARNING("%s: Bad len in attr_rsp %d", __func__, attr_len); | |
826 | + return (NULL); | |
827 | + } | |
814 | 828 | if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2)) |
815 | 829 | { |
816 | 830 | SDP_TRACE_WARNING ("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type, attr_len); |
@@ -900,7 +914,11 @@ static UINT8 *add_attr (UINT8 *p, UINT8 *p_end, tSDP_DISCOVERY_DB *p_db, tSDP_DI | ||
900 | 914 | nest_level &= ~(SDP_ADDITIONAL_LIST_MASK); |
901 | 915 | |
902 | 916 | type = *p++; |
903 | - p = sdpu_get_len_from_type (p, type, &attr_len); | |
917 | + p = sdpu_get_len_from_type (p, p_end, type, &attr_len); | |
918 | + if (p == NULL || (p + attr_len) > p_end) { | |
919 | + SDP_TRACE_WARNING("%s: bad length in attr_rsp", __func__); | |
920 | + return NULL; | |
921 | + } | |
904 | 922 | |
905 | 923 | attr_len &= SDP_DISC_ATTR_LEN_MASK; |
906 | 924 | attr_type = (type >> 3) & 0x0f; |
@@ -598,7 +598,7 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq) | ||
598 | 598 | ** Returns void |
599 | 599 | ** |
600 | 600 | *******************************************************************************/ |
601 | -UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len) | |
601 | +UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 *p_end, UINT8 type, UINT32 *p_len) | |
602 | 602 | { |
603 | 603 | UINT8 u8; |
604 | 604 | UINT16 u16; |
@@ -622,14 +622,26 @@ UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len) | ||
622 | 622 | *p_len = 16; |
623 | 623 | break; |
624 | 624 | case SIZE_IN_NEXT_BYTE: |
625 | + if (p + 1 > p_end) { | |
626 | + *p_len = 0; | |
627 | + return NULL; | |
628 | + } | |
625 | 629 | BE_STREAM_TO_UINT8 (u8, p); |
626 | 630 | *p_len = u8; |
627 | 631 | break; |
628 | 632 | case SIZE_IN_NEXT_WORD: |
633 | + if (p + 2 > p_end) { | |
634 | + *p_len = 0; | |
635 | + return NULL; | |
636 | + } | |
629 | 637 | BE_STREAM_TO_UINT16 (u16, p); |
630 | 638 | *p_len = u16; |
631 | 639 | break; |
632 | 640 | case SIZE_IN_NEXT_LONG: |
641 | + if (p + 4 > p_end) { | |
642 | + *p_len = 0; | |
643 | + return NULL; | |
644 | + } | |
633 | 645 | BE_STREAM_TO_UINT32 (u32, p); |
634 | 646 | *p_len = (UINT16) u32; |
635 | 647 | break; |
@@ -282,7 +282,7 @@ extern void sdpu_build_n_send_error (tCONN_CB *p_ccb, UINT16 trans_num, UIN | ||
282 | 282 | extern UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq); |
283 | 283 | extern UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq); |
284 | 284 | |
285 | -extern UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len); | |
285 | +extern UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 *p_end, UINT8 type, UINT32 *p_len); | |
286 | 286 | extern BOOLEAN sdpu_is_base_uuid (UINT8 *p_uuid); |
287 | 287 | extern BOOLEAN sdpu_compare_uuid_arrays (UINT8 *p_uuid1, UINT32 len1, UINT8 *p_uuid2, UINT16 len2); |
288 | 288 | extern BOOLEAN sdpu_compare_bt_uuids (tBT_UUID *p_uuid1, tBT_UUID *p_uuid2); |