mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-23 22:49:28 -05:00
184 lines
6.9 KiB
Diff
184 lines
6.9 KiB
Diff
|
From 3d89c4fb28b44ad5cbc0e75315e28b96eaee95db Mon Sep 17 00:00:00 2001
|
||
|
From: Ted Wang <tedwang@google.com>
|
||
|
Date: Mon, 29 Apr 2019 10:11:04 +0800
|
||
|
Subject: [PATCH] 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)
|
||
|
---
|
||
|
stack/sdp/sdp_db.c | 7 ++++++-
|
||
|
stack/sdp/sdp_discovery.c | 37 ++++++++++++++++++++++++++++---------
|
||
|
stack/sdp/sdp_utils.c | 17 ++++++++++++++++-
|
||
|
stack/sdp/sdpint.h | 2 +-
|
||
|
4 files changed, 51 insertions(+), 12 deletions(-)
|
||
|
|
||
|
diff --git a/stack/sdp/sdp_db.c b/stack/sdp/sdp_db.c
|
||
|
index 318a8cc2..f9518f77 100644
|
||
|
--- a/stack/sdp/sdp_db.c
|
||
|
+++ b/stack/sdp/sdp_db.c
|
||
|
@@ -130,7 +130,12 @@ static BOOLEAN find_uuid_in_seq (UINT8 *p , UINT32 seq_len, UINT8 *p_uuid,
|
||
|
while (p < p_end)
|
||
|
{
|
||
|
type = *p++;
|
||
|
- p = sdpu_get_len_from_type (p, type, &len);
|
||
|
+ p = sdpu_get_len_from_type (p, p_end, type, &len);
|
||
|
+ if (p == NULL || (p + len) > p_end)
|
||
|
+ {
|
||
|
+ SDP_TRACE_WARNING1("%s: bad length", __func__);
|
||
|
+ break;
|
||
|
+ }
|
||
|
type = type >> 3;
|
||
|
if (type == UUID_DESC_TYPE)
|
||
|
{
|
||
|
diff --git a/stack/sdp/sdp_discovery.c b/stack/sdp/sdp_discovery.c
|
||
|
index d92d1e52..81b5d584 100644
|
||
|
--- a/stack/sdp/sdp_discovery.c
|
||
|
+++ b/stack/sdp/sdp_discovery.c
|
||
|
@@ -408,6 +408,7 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset)
|
||
|
UINT32 list_len;
|
||
|
UINT8 *p;
|
||
|
UINT8 * p_temp;
|
||
|
+ UINT8 *p_end;
|
||
|
UINT8 type;
|
||
|
UINT32 delta_len = 0;
|
||
|
|
||
|
@@ -427,13 +428,19 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset)
|
||
|
cpy_len = p_ccb->p_db->raw_size - p_ccb->p_db->raw_used;
|
||
|
list_len = p_ccb->list_len;
|
||
|
p_temp = p = &p_ccb->rsp_list[0];
|
||
|
+ p_end = &p_ccb->rsp_list[0] + list_len;
|
||
|
|
||
|
if(offset)
|
||
|
{
|
||
|
cpy_len -= 1;
|
||
|
type = *p++;
|
||
|
uint8_t* old_p = p;
|
||
|
- p = sdpu_get_len_from_type (p, type, &list_len);
|
||
|
+ p = sdpu_get_len_from_type(p, p_end, type, &list_len);
|
||
|
+ if (p == NULL || (p + list_len) > p_end)
|
||
|
+ {
|
||
|
+ SDP_TRACE_WARNING1("%s: bad length", __func__);
|
||
|
+ return;
|
||
|
+ }
|
||
|
if ((int)cpy_len < (p - old_p))
|
||
|
{
|
||
|
SDP_TRACE_WARNING1("%s: no bytes left for data", __func__);
|
||
|
@@ -810,8 +817,12 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply,
|
||
|
SDP_TRACE_WARNING1 ("SDP - Wrong type: 0x%02x in attr_rsp", type);
|
||
|
return;
|
||
|
}
|
||
|
- p = sdpu_get_len_from_type (p, type, &seq_len);
|
||
|
-
|
||
|
+ p = sdpu_get_len_from_type(p, p + p_ccb->list_len, type, &seq_len);
|
||
|
+ if (p == NULL || (p + seq_len) > (p + p_ccb->list_len))
|
||
|
+ {
|
||
|
+ SDP_TRACE_WARNING1("%s: bad length", __func__);
|
||
|
+ return;
|
||
|
+ }
|
||
|
p_end = &p_ccb->rsp_list[p_ccb->list_len];
|
||
|
|
||
|
if ((p + seq_len) != p_end)
|
||
|
@@ -858,9 +869,8 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end)
|
||
|
SDP_TRACE_WARNING1 ("SDP - Wrong type: 0x%02x in attr_rsp", type);
|
||
|
return (NULL);
|
||
|
}
|
||
|
-
|
||
|
- p = sdpu_get_len_from_type (p, type, &seq_len);
|
||
|
- if ((p + seq_len) > p_msg_end)
|
||
|
+ p = sdpu_get_len_from_type(p, p_msg_end, type, &seq_len);
|
||
|
+ if (p == NULL || (p + seq_len) > p_msg_end)
|
||
|
{
|
||
|
SDP_TRACE_WARNING1 ("SDP - Bad len in attr_rsp %d", seq_len);
|
||
|
return (NULL);
|
||
|
@@ -880,7 +890,12 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end)
|
||
|
{
|
||
|
/* First get the attribute ID */
|
||
|
type = *p++;
|
||
|
- p = sdpu_get_len_from_type (p, type, &attr_len);
|
||
|
+ p = sdpu_get_len_from_type(p, p_msg_end, type, &attr_len);
|
||
|
+ if (p == NULL || (p + attr_len) > p_seq_end)
|
||
|
+ {
|
||
|
+ SDP_TRACE_WARNING2("%s: Bad len in attr_rsp %d", __func__, attr_len);
|
||
|
+ return (NULL);
|
||
|
+ }
|
||
|
if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2))
|
||
|
{
|
||
|
SDP_TRACE_WARNING2 ("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type, attr_len);
|
||
|
@@ -970,8 +985,12 @@ static UINT8 *add_attr (UINT8 *p, UINT8 *p_end, tSDP_DISCOVERY_DB *p_db, tSDP_DI
|
||
|
nest_level &= ~(SDP_ADDITIONAL_LIST_MASK);
|
||
|
|
||
|
type = *p++;
|
||
|
- p = sdpu_get_len_from_type (p, type, &attr_len);
|
||
|
-
|
||
|
+ p = sdpu_get_len_from_type(p, p_end, type, &attr_len);
|
||
|
+ if (p == NULL || (p + attr_len) > p_end)
|
||
|
+ {
|
||
|
+ SDP_TRACE_WARNING1("%s: bad length in attr_rsp", __func__);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
attr_len &= SDP_DISC_ATTR_LEN_MASK;
|
||
|
attr_type = (type >> 3) & 0x0f;
|
||
|
|
||
|
diff --git a/stack/sdp/sdp_utils.c b/stack/sdp/sdp_utils.c
|
||
|
index 210fbcc8..c99378b8 100644
|
||
|
--- a/stack/sdp/sdp_utils.c
|
||
|
+++ b/stack/sdp/sdp_utils.c
|
||
|
@@ -608,7 +608,7 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq)
|
||
|
** Returns void
|
||
|
**
|
||
|
*******************************************************************************/
|
||
|
-UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len)
|
||
|
+UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 *p_end, UINT8 type, UINT32 *p_len)
|
||
|
{
|
||
|
UINT8 u8;
|
||
|
UINT16 u16;
|
||
|
@@ -632,14 +632,29 @@ UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len)
|
||
|
*p_len = 16;
|
||
|
break;
|
||
|
case SIZE_IN_NEXT_BYTE:
|
||
|
+ if (p + 1 > p_end)
|
||
|
+ {
|
||
|
+ *p_len = 0;
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
BE_STREAM_TO_UINT8 (u8, p);
|
||
|
*p_len = u8;
|
||
|
break;
|
||
|
case SIZE_IN_NEXT_WORD:
|
||
|
+ if (p + 2 > p_end)
|
||
|
+ {
|
||
|
+ *p_len = 0;
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
BE_STREAM_TO_UINT16 (u16, p);
|
||
|
*p_len = u16;
|
||
|
break;
|
||
|
case SIZE_IN_NEXT_LONG:
|
||
|
+ if (p + 4 > p_end)
|
||
|
+ {
|
||
|
+ *p_len = 0;
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
BE_STREAM_TO_UINT32 (u32, p);
|
||
|
*p_len = (UINT16) u32;
|
||
|
break;
|
||
|
diff --git a/stack/sdp/sdpint.h b/stack/sdp/sdpint.h
|
||
|
index b3006640..74f748aa 100644
|
||
|
--- a/stack/sdp/sdpint.h
|
||
|
+++ b/stack/sdp/sdpint.h
|
||
|
@@ -285,7 +285,7 @@ extern void sdpu_build_n_send_error (tCONN_CB *p_ccb, UINT16 trans_num, UIN
|
||
|
extern UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq);
|
||
|
extern UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq);
|
||
|
|
||
|
-SDP_API extern UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len);
|
||
|
+SDP_API extern UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 *p_end, UINT8 type, UINT32 *p_len);
|
||
|
extern BOOLEAN sdpu_is_base_uuid (UINT8 *p_uuid);
|
||
|
extern BOOLEAN sdpu_compare_uuid_arrays (UINT8 *p_uuid1, UINT32 len1, UINT8 *p_uuid2, UINT16 len2);
|
||
|
SDP_API extern BOOLEAN sdpu_compare_bt_uuids (tBT_UUID *p_uuid1, tBT_UUID *p_uuid2);
|