Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abd0cc42 authored by Ted Wang's avatar Ted Wang
Browse files

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
parent 342e5538
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -129,7 +129,11 @@ static BOOLEAN find_uuid_in_seq (UINT8 *p , UINT32 seq_len, UINT8 *p_uuid,
    while (p < p_end)
    while (p < p_end)
    {
    {
        type = *p++;
        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_WARNING("%s: bad length", __func__);
            break;
        }
        type = type >> 3;
        type = type >> 3;
        if (type == UUID_DESC_TYPE)
        if (type == UUID_DESC_TYPE)
        {
        {
+24 −6
Original line number Original line Diff line number Diff line
@@ -367,6 +367,7 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset)
    unsigned int    cpy_len, rem_len;
    unsigned int    cpy_len, rem_len;
    UINT32          list_len;
    UINT32          list_len;
    UINT8           *p;
    UINT8           *p;
    UINT8           *p_end;
    UINT8           type;
    UINT8           type;


#if (SDP_DEBUG_RAW == TRUE)
#if (SDP_DEBUG_RAW == TRUE)
@@ -385,13 +386,18 @@ 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;
        cpy_len = p_ccb->p_db->raw_size - p_ccb->p_db->raw_used;
        list_len = p_ccb->list_len;
        list_len = p_ccb->list_len;
        p = &p_ccb->rsp_list[0];
        p = &p_ccb->rsp_list[0];
        p_end = &p_ccb->rsp_list[0] + list_len;


        if(offset)
        if(offset)
        {
        {
            cpy_len -= 1;
            cpy_len -= 1;
            type = *p++;
            type = *p++;
            uint8_t* old_p = 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_WARNING("%s: bad length", __func__);
                return;
            }
            if ((int)cpy_len < (p - old_p)) {
            if ((int)cpy_len < (p - old_p)) {
                SDP_TRACE_WARNING("%s: no bytes left for data", __func__);
                SDP_TRACE_WARNING("%s: no bytes left for data", __func__);
                return;
                return;
@@ -739,7 +745,11 @@ static void process_service_search_attr_rsp(tCONN_CB *p_ccb, UINT8 *p_reply,
        SDP_TRACE_WARNING ("SDP - Wrong type: 0x%02x in attr_rsp", type);
        SDP_TRACE_WARNING ("SDP - Wrong type: 0x%02x in attr_rsp", type);
        return;
        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_WARNING("%s: bad length", __func__);
        return;
    }


    p_end = &p_ccb->rsp_list[p_ccb->list_len];
    p_end = &p_ccb->rsp_list[p_ccb->list_len];


@@ -788,8 +798,8 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end)
        return (NULL);
        return (NULL);
    }
    }


    p = sdpu_get_len_from_type (p, type, &seq_len);
    p = sdpu_get_len_from_type (p, p_msg_end, type, &seq_len);
    if ((p + seq_len) > p_msg_end)
    if (p == NULL || (p + seq_len) > p_msg_end)
    {
    {
        SDP_TRACE_WARNING ("SDP - Bad len in attr_rsp %d", seq_len);
        SDP_TRACE_WARNING ("SDP - Bad len in attr_rsp %d", seq_len);
        return (NULL);
        return (NULL);
@@ -809,7 +819,11 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end)
    {
    {
        /* First get the attribute ID */
        /* First get the attribute ID */
        type = *p++;
        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_WARNING("%s: Bad len in attr_rsp %d", __func__, attr_len);
            return (NULL);
        }
        if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2))
        if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2))
        {
        {
            SDP_TRACE_WARNING ("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type, attr_len);
            SDP_TRACE_WARNING ("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type, attr_len);
@@ -899,7 +913,11 @@ static UINT8 *add_attr (UINT8 *p, UINT8 *p_end, tSDP_DISCOVERY_DB *p_db, tSDP_DI
    nest_level &= ~(SDP_ADDITIONAL_LIST_MASK);
    nest_level &= ~(SDP_ADDITIONAL_LIST_MASK);


    type = *p++;
    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_WARNING("%s: bad length in attr_rsp", __func__);
        return NULL;
    }


    attr_len &= SDP_DISC_ATTR_LEN_MASK;
    attr_len &= SDP_DISC_ATTR_LEN_MASK;
    attr_type = (type >> 3) & 0x0f;
    attr_type = (type >> 3) & 0x0f;
+13 −1
Original line number Original line Diff line number Diff line
@@ -598,7 +598,7 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq)
** Returns          void
** 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;
    UINT8   u8;
    UINT16  u16;
    UINT16  u16;
@@ -622,14 +622,26 @@ UINT8 *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len)
        *p_len = 16;
        *p_len = 16;
        break;
        break;
    case SIZE_IN_NEXT_BYTE:
    case SIZE_IN_NEXT_BYTE:
        if (p + 1 > p_end) {
            *p_len = 0;
            return NULL;
        }
        BE_STREAM_TO_UINT8 (u8, p);
        BE_STREAM_TO_UINT8 (u8, p);
        *p_len = u8;
        *p_len = u8;
        break;
        break;
    case SIZE_IN_NEXT_WORD:
    case SIZE_IN_NEXT_WORD:
        if (p + 2 > p_end) {
            *p_len = 0;
            return NULL;
        }
        BE_STREAM_TO_UINT16 (u16, p);
        BE_STREAM_TO_UINT16 (u16, p);
        *p_len = u16;
        *p_len = u16;
        break;
        break;
    case SIZE_IN_NEXT_LONG:
    case SIZE_IN_NEXT_LONG:
        if (p + 4 > p_end) {
            *p_len = 0;
            return NULL;
        }
        BE_STREAM_TO_UINT32 (u32, p);
        BE_STREAM_TO_UINT32 (u32, p);
        *p_len = (UINT16) u32;
        *p_len = (UINT16) u32;
        break;
        break;
+1 −1
Original line number Original line Diff line number Diff line
@@ -282,7 +282,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_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);
extern UINT8    *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq);


extern UINT8    *sdpu_get_len_from_type (UINT8 *p, UINT8 type, UINT32 *p_len);
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_is_base_uuid (UINT8 *p_uuid);
extern BOOLEAN  sdpu_compare_uuid_arrays (UINT8 *p_uuid1, UINT32 len1, UINT8 *p_uuid2, UINT16 len2);
extern BOOLEAN  sdpu_compare_uuid_arrays (UINT8 *p_uuid1, UINT32 len1, UINT8 *p_uuid2, UINT16 len2);
extern BOOLEAN  sdpu_compare_bt_uuids (tBT_UUID *p_uuid1, tBT_UUID *p_uuid2);
extern BOOLEAN  sdpu_compare_bt_uuids (tBT_UUID *p_uuid1, tBT_UUID *p_uuid2);