diff options
author | Myles Watson <mylesgw@google.com> | 2018-01-11 17:43:40 -0800 |
---|---|---|
committer | Andreas Blaesius <andi@unlegacy-android.org> | 2018-04-14 14:02:06 +0200 |
commit | a490759d3569efe6e94bef306865a4f8e01b3656 (patch) | |
tree | c8f04ee2d54f94c547538eca2f4b3665242b4dda /stack/sdp/sdp_utils.c | |
parent | 178c0ff3a46a9a633822414ddeaed6aa0e536ba9 (diff) | |
download | android_system_bt-a490759d3569efe6e94bef306865a4f8e01b3656.tar.gz android_system_bt-a490759d3569efe6e94bef306865a4f8e01b3656.tar.bz2 android_system_bt-a490759d3569efe6e94bef306865a4f8e01b3656.zip |
SDP: Check p_req_end before reading from p_req
Bug: 69384124
Test: Connect a headset
Change-Id: Ia30c58ed39977552e5ddc21cc3c1b54c6b1d8abe
Merged-In: Ia30c58ed39977552e5ddc21cc3c1b54c6b1d8abe
(cherry picked from commit dd856fbc4ade8f7d78873db3533b4c9fd7c6d612)
Diffstat (limited to 'stack/sdp/sdp_utils.c')
-rw-r--r-- | stack/sdp/sdp_utils.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/stack/sdp/sdp_utils.c b/stack/sdp/sdp_utils.c index d9b1ea7ef..02af9f971 100644 --- a/stack/sdp/sdp_utils.c +++ b/stack/sdp/sdp_utils.c @@ -382,6 +382,8 @@ UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq) p_seq->num_uids = 0; /* A UID sequence is composed of a bunch of UIDs. */ + if (sizeof(descr) > param_len) return (NULL); + param_len -= sizeof(descr); BE_STREAM_TO_UINT8 (descr, p); type = descr >> 3; @@ -402,19 +404,25 @@ UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq) seq_len = 16; break; case SIZE_IN_NEXT_BYTE: + if (sizeof(uint8_t) > param_len) return (NULL); + param_len -= sizeof(uint8_t); BE_STREAM_TO_UINT8 (seq_len, p); break; case SIZE_IN_NEXT_WORD: + if (sizeof(uint16_t) > param_len) return (NULL); + param_len -= sizeof(uint16_t); BE_STREAM_TO_UINT16 (seq_len, p); break; case SIZE_IN_NEXT_LONG: + if (sizeof(uint32_t) > param_len) return (NULL); + param_len -= sizeof(uint32_t); BE_STREAM_TO_UINT32 (seq_len, p); break; default: return (NULL); } - if (seq_len >= param_len) + if (seq_len > param_len) return (NULL); p_seq_end = p + seq_len; @@ -441,12 +449,15 @@ UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq) uuid_len = 16; break; case SIZE_IN_NEXT_BYTE: + if (p + sizeof(uint8_t) > p_seq_end) return NULL; BE_STREAM_TO_UINT8 (uuid_len, p); break; case SIZE_IN_NEXT_WORD: + if (p + sizeof(uint16_t) > p_seq_end) return NULL; BE_STREAM_TO_UINT16 (uuid_len, p); break; case SIZE_IN_NEXT_LONG: + if (p + sizeof(uint32_t) > p_seq_end) return NULL; BE_STREAM_TO_UINT32 (uuid_len, p); break; default: @@ -454,7 +465,8 @@ UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq) } /* If UUID length is valid, copy it across */ - if ((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) + if (((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) && + (p + uuid_len <= p_seq_end)) { p_seq->uuid_entry[p_seq->num_uids].len = (UINT16) uuid_len; BE_STREAM_TO_ARRAY (p, p_seq->uuid_entry[p_seq->num_uids].value, (int)uuid_len); @@ -496,33 +508,41 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq) p_seq->num_attr = 0; /* Get attribute sequence info */ + if (param_len < sizeof(descr)) return NULL; + param_len -= sizeof(descr); BE_STREAM_TO_UINT8 (descr, p); type = descr >> 3; size = descr & 7; if (type != DATA_ELE_SEQ_DESC_TYPE) - return (p); + return NULL; switch (size) { case SIZE_IN_NEXT_BYTE: + if (param_len < sizeof(uint8_t)) return NULL; + param_len -= sizeof(uint8_t); BE_STREAM_TO_UINT8 (list_len, p); break; case SIZE_IN_NEXT_WORD: + if (param_len < sizeof(uint16_t)) return NULL; + param_len -= sizeof(uint16_t); BE_STREAM_TO_UINT16 (list_len, p); break; case SIZE_IN_NEXT_LONG: + if (param_len < sizeof(uint32_t)) return NULL; + param_len -= sizeof(uint32_t); BE_STREAM_TO_UINT32 (list_len, p); break; default: - return (p); + return NULL; } if (list_len > param_len) - return (p); + return NULL; p_end_list = p + list_len; @@ -534,7 +554,7 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq) size = descr & 7; if (type != UINT_DESC_TYPE) - return (p); + return NULL; switch (size) { @@ -545,20 +565,24 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq) attr_len = 4; break; case SIZE_IN_NEXT_BYTE: + if (p + sizeof(uint8_t) > p_end_list) return NULL; BE_STREAM_TO_UINT8 (attr_len, p); break; case SIZE_IN_NEXT_WORD: + if (p + sizeof(uint16_t) > p_end_list) return NULL; BE_STREAM_TO_UINT16 (attr_len, p); break; case SIZE_IN_NEXT_LONG: + if (p + sizeof(uint32_t) > p_end_list) return NULL; BE_STREAM_TO_UINT32 (attr_len, p); break; default: - return (NULL); + return NULL; break; } /* Attribute length must be 2-bytes or 4-bytes for a paired entry. */ + if (p + attr_len > p_end_list) return NULL; if (attr_len == 2) { BE_STREAM_TO_UINT16 (p_seq->attr_entry[p_seq->num_attr].start, p); |