SDP: Check p_end in save_attr_seq and add_attr
Bug: 115900043
Test: Sanity pairing and SDP PTS
Change-Id: Ib642f79ed22b65ede5ff786cb1e163d172480f11
(cherry picked from commit b8a5081b00fc9730092d8392786f3f4e659cb602)
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index 95f55bf..1ca2ad3 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -55,7 +55,7 @@
static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end);
static tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db,
const RawAddress& p_bda);
-static uint8_t* add_attr(uint8_t* p, tSDP_DISCOVERY_DB* p_db,
+static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db,
tSDP_DISC_REC* p_rec, uint16_t attr_id,
tSDP_DISC_ATTR* p_parent_attr, uint8_t nest_level);
@@ -770,7 +770,7 @@
BE_STREAM_TO_UINT16(attr_id, p);
/* Now, add the attribute value */
- p = add_attr(p, p_ccb->p_db, p_rec, attr_id, NULL, 0);
+ p = add_attr(p, p_seq_end, p_ccb->p_db, p_rec, attr_id, NULL, 0);
if (!p) {
SDP_TRACE_WARNING("SDP - DB full add_attr");
@@ -830,7 +830,7 @@
* Returns pointer to next byte in data stream
*
******************************************************************************/
-static uint8_t* add_attr(uint8_t* p, tSDP_DISCOVERY_DB* p_db,
+static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db,
tSDP_DISC_REC* p_rec, uint16_t attr_id,
tSDP_DISC_ATTR* p_parent_attr, uint8_t nest_level) {
tSDP_DISC_ATTR* p_attr;
@@ -839,7 +839,7 @@
uint16_t attr_type;
uint16_t id;
uint8_t type;
- uint8_t* p_end;
+ uint8_t* p_attr_end;
uint8_t is_additional_list = nest_level & SDP_ADDITIONAL_LIST_MASK;
nest_level &= ~(SDP_ADDITIONAL_LIST_MASK);
@@ -856,6 +856,13 @@
else
total_len = sizeof(tSDP_DISC_ATTR);
+ p_attr_end = p + attr_len;
+ if (p_attr_end > p_end) {
+ android_errorWriteLog(0x534e4554, "115900043");
+ SDP_TRACE_WARNING("%s: SDP - Attribute length beyond p_end", __func__);
+ return NULL;
+ }
+
/* Ensure it is a multiple of 4 */
total_len = (total_len + 3) & ~3;
@@ -879,18 +886,17 @@
* sub-attributes */
p_db->p_free_mem += sizeof(tSDP_DISC_ATTR);
p_db->mem_free -= sizeof(tSDP_DISC_ATTR);
- p_end = p + attr_len;
total_len = 0;
/* SDP_TRACE_DEBUG ("SDP - attr nest level:%d(list)", nest_level); */
if (nest_level >= MAX_NEST_LEVELS) {
SDP_TRACE_ERROR("SDP - attr nesting too deep");
- return (p_end);
+ return p_attr_end;
}
/* Now, add the list entry */
- p = add_attr(p, p_db, p_rec, ATTR_ID_PROTOCOL_DESC_LIST, p_attr,
- (uint8_t)(nest_level + 1));
+ p = add_attr(p, p_end, p_db, p_rec, ATTR_ID_PROTOCOL_DESC_LIST,
+ p_attr, (uint8_t)(nest_level + 1));
break;
}
@@ -949,7 +955,7 @@
break;
default:
SDP_TRACE_WARNING("SDP - bad len in UUID attr: %d", attr_len);
- return (p + attr_len);
+ return p_attr_end;
}
break;
@@ -959,22 +965,22 @@
* sub-attributes */
p_db->p_free_mem += sizeof(tSDP_DISC_ATTR);
p_db->mem_free -= sizeof(tSDP_DISC_ATTR);
- p_end = p + attr_len;
total_len = 0;
/* SDP_TRACE_DEBUG ("SDP - attr nest level:%d", nest_level); */
if (nest_level >= MAX_NEST_LEVELS) {
SDP_TRACE_ERROR("SDP - attr nesting too deep");
- return (p_end);
+ return p_attr_end;
}
if (is_additional_list != 0 ||
attr_id == ATTR_ID_ADDITION_PROTO_DESC_LISTS)
nest_level |= SDP_ADDITIONAL_LIST_MASK;
/* SDP_TRACE_DEBUG ("SDP - attr nest level:0x%x(finish)", nest_level); */
- while (p < p_end) {
+ while (p < p_attr_end) {
/* Now, add the list entry */
- p = add_attr(p, p_db, p_rec, 0, p_attr, (uint8_t)(nest_level + 1));
+ p = add_attr(p, p_end, p_db, p_rec, 0, p_attr,
+ (uint8_t)(nest_level + 1));
if (!p) return (NULL);
}
@@ -992,7 +998,7 @@
break;
default:
SDP_TRACE_WARNING("SDP - bad len in boolean attr: %d", attr_len);
- return (p + attr_len);
+ return p_attr_end;
}
break;