system/bt
Revisão | 1955a18c8da716ac45e5b8cf6f9837fe2dc0ab5d (tree) |
---|---|
Hora | 2019-07-04 02:12:52 |
Autor | Ted Wang <tedwang@goog...> |
Commiter | Vasyl Gello |
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 1243f8da338dadfe2a3c281a08297b431402d41c)
(cherry picked from commit 4d8e1d63e1a2116c47702d38d858f5a742e8292f)
@@ -129,7 +129,12 @@ 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 | + { | |
135 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
136 | + break; | |
137 | + } | |
133 | 138 | type = type >> 3; |
134 | 139 | if (type == UUID_DESC_TYPE) |
135 | 140 | { |
@@ -373,6 +373,7 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset) | ||
373 | 373 | unsigned int cpy_len, rem_len; |
374 | 374 | UINT32 list_len; |
375 | 375 | UINT8 *p; |
376 | + UINT8 *p_end; | |
376 | 377 | UINT8 type; |
377 | 378 | |
378 | 379 | #if (SDP_DEBUG_RAW == TRUE) |
@@ -391,13 +392,19 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset) | ||
391 | 392 | cpy_len = p_ccb->p_db->raw_size - p_ccb->p_db->raw_used; |
392 | 393 | list_len = p_ccb->list_len; |
393 | 394 | p = &p_ccb->rsp_list[0]; |
395 | + p_end = &p_ccb->rsp_list[0] + list_len; | |
394 | 396 | |
395 | 397 | if(offset) |
396 | 398 | { |
397 | 399 | cpy_len -= 1; |
398 | 400 | type = *p++; |
399 | 401 | uint8_t* old_p = p; |
400 | - p = sdpu_get_len_from_type (p, type, &list_len); | |
402 | + p = sdpu_get_len_from_type(p, p_end, type, &list_len); | |
403 | + if (p == NULL || (p + list_len) > p_end) | |
404 | + { | |
405 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
406 | + return; | |
407 | + } | |
401 | 408 | if ((int)cpy_len < (p - old_p)) |
402 | 409 | { |
403 | 410 | SDP_TRACE_WARNING("%s: no bytes left for data", __func__); |
@@ -752,8 +759,12 @@ static void process_service_search_attr_rsp (tCONN_CB* p_ccb, uint8_t* p_reply, | ||
752 | 759 | SDP_TRACE_WARNING ("SDP - Wrong type: 0x%02x in attr_rsp", type); |
753 | 760 | return; |
754 | 761 | } |
755 | - p = sdpu_get_len_from_type (p, type, &seq_len); | |
756 | - | |
762 | + p = sdpu_get_len_from_type(p, p + p_ccb->list_len, type, &seq_len); | |
763 | + if (p == NULL || (p + seq_len) > (p + p_ccb->list_len)) | |
764 | + { | |
765 | + SDP_TRACE_WARNING("%s: bad length", __func__); | |
766 | + return; | |
767 | + } | |
757 | 768 | p_end = &p_ccb->rsp_list[p_ccb->list_len]; |
758 | 769 | |
759 | 770 | if ((p + seq_len) != p_end) |
@@ -800,9 +811,8 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end) | ||
800 | 811 | SDP_TRACE_WARNING ("SDP - Wrong type: 0x%02x in attr_rsp", type); |
801 | 812 | return (NULL); |
802 | 813 | } |
803 | - | |
804 | - p = sdpu_get_len_from_type (p, type, &seq_len); | |
805 | - if ((p + seq_len) > p_msg_end) | |
814 | + p = sdpu_get_len_from_type(p, p_msg_end, type, &seq_len); | |
815 | + if (p == NULL || (p + seq_len) > p_msg_end) | |
806 | 816 | { |
807 | 817 | SDP_TRACE_WARNING ("SDP - Bad len in attr_rsp %d", seq_len); |
808 | 818 | return (NULL); |
@@ -822,7 +832,12 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end) | ||
822 | 832 | { |
823 | 833 | /* First get the attribute ID */ |
824 | 834 | type = *p++; |
825 | - p = sdpu_get_len_from_type (p, type, &attr_len); | |
835 | + p = sdpu_get_len_from_type(p, p_msg_end, type, &attr_len); | |
836 | + if (p == NULL || (p + attr_len) > p_seq_end) | |
837 | + { | |
838 | + SDP_TRACE_WARNING("%s: Bad len in attr_rsp %d", __func__, attr_len); | |
839 | + return (NULL); | |
840 | + } | |
826 | 841 | if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2)) |
827 | 842 | { |
828 | 843 | SDP_TRACE_WARNING ("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type, attr_len); |
@@ -912,8 +927,12 @@ static UINT8 *add_attr (UINT8 *p, UINT8 *p_end, tSDP_DISCOVERY_DB *p_db, tSDP_DI | ||
912 | 927 | nest_level &= ~(SDP_ADDITIONAL_LIST_MASK); |
913 | 928 | |
914 | 929 | type = *p++; |
915 | - p = sdpu_get_len_from_type (p, type, &attr_len); | |
916 | - | |
930 | + p = sdpu_get_len_from_type(p, p_end, type, &attr_len); | |
931 | + if (p == NULL || (p + attr_len) > p_end) | |
932 | + { | |
933 | + SDP_TRACE_WARNING("%s: bad length in attr_rsp", __func__); | |
934 | + return NULL; | |
935 | + } | |
917 | 936 | attr_len &= SDP_DISC_ATTR_LEN_MASK; |
918 | 937 | attr_type = (type >> 3) & 0x0f; |
919 | 938 |
@@ -637,7 +637,8 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq) | ||
637 | 637 | ** Returns void |
638 | 638 | ** |
639 | 639 | *******************************************************************************/ |
640 | -UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len) | |
640 | +UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 *p_end, UINT8 type, | |
641 | + UINT32 *p_len) | |
641 | 642 | { |
642 | 643 | UINT8 u8; |
643 | 644 | UINT16 u16; |
@@ -661,14 +662,29 @@ UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len) | ||
661 | 662 | *p_len = 16; |
662 | 663 | break; |
663 | 664 | case SIZE_IN_NEXT_BYTE: |
665 | + if (p + 1 > p_end) | |
666 | + { | |
667 | + *p_len = 0; | |
668 | + return NULL; | |
669 | + } | |
664 | 670 | BE_STREAM_TO_UINT8 (u8, p); |
665 | 671 | *p_len = u8; |
666 | 672 | break; |
667 | 673 | case SIZE_IN_NEXT_WORD: |
674 | + if (p + 2 > p_end) | |
675 | + { | |
676 | + *p_len = 0; | |
677 | + return NULL; | |
678 | + } | |
668 | 679 | BE_STREAM_TO_UINT16 (u16, p); |
669 | 680 | *p_len = u16; |
670 | 681 | break; |
671 | 682 | case SIZE_IN_NEXT_LONG: |
683 | + if (p + 4 > p_end) | |
684 | + { | |
685 | + *p_len = 0; | |
686 | + return NULL; | |
687 | + } | |
672 | 688 | BE_STREAM_TO_UINT32 (u32, p); |
673 | 689 | *p_len = (UINT16) u32; |
674 | 690 | break; |
@@ -284,7 +284,7 @@ extern void sdpu_build_n_send_error (tCONN_CB *p_ccb, UINT16 trans_num, UIN | ||
284 | 284 | extern UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq); |
285 | 285 | extern UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq); |
286 | 286 | |
287 | -extern UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len); | |
287 | +extern UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 *p_end, UINT8 type, UINT32 *p_len); | |
288 | 288 | extern BOOLEAN sdpu_is_base_uuid (UINT8 *p_uuid); |
289 | 289 | extern BOOLEAN sdpu_compare_uuid_arrays (UINT8 *p_uuid1, UINT32 len1, UINT8 *p_uuid2, UINT16 len2); |
290 | 290 | extern BOOLEAN sdpu_compare_bt_uuids (tBT_UUID *p_uuid1, tBT_UUID *p_uuid2); |