Merge cherrypicks of ['googleplex-android-review.googlesource.com/22343125', 'googleplex-android-review.googlesource.com/22188831'] into security-aosp-tm-release.
Change-Id: I5f2993c46e95a744131fea454e8dab560a54fd30
diff --git a/system/stack/btm/btm_ble_gap.cc b/system/stack/btm/btm_ble_gap.cc
index c2fda91..b4e52f6 100644
--- a/system/stack/btm/btm_ble_gap.cc
+++ b/system/stack/btm/btm_ble_gap.cc
@@ -1165,6 +1165,10 @@
LOG_DEBUG("[PSync]: sync_handle = %d", sync_handle);
int index = btm_ble_get_psync_index_from_handle(sync_handle);
+ if (index == MAX_SYNC_TRANSACTION) {
+ LOG_ERROR("[PSync]: index not found for handle %u", sync_handle);
+ return;
+ }
tBTM_BLE_PERIODIC_SYNC* ps = &btm_ble_pa_sync_cb.p_sync[index];
ps->sync_lost_cb.Run(sync_handle);
diff --git a/system/stack/sdp/sdp_discovery.cc b/system/stack/sdp/sdp_discovery.cc
index a6ad62b..38db635 100644
--- a/system/stack/sdp/sdp_discovery.cc
+++ b/system/stack/sdp/sdp_discovery.cc
@@ -70,10 +70,15 @@
*
******************************************************************************/
static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids,
- Uuid* p_uuid_list) {
+ Uuid* p_uuid_list, uint16_t& bytes_left) {
uint16_t xx;
uint8_t* p_len;
+ if (bytes_left < 2) {
+ DCHECK(0) << "SDP: No space for data element header";
+ return (p_out);
+ }
+
/* First thing is the data element header */
UINT8_TO_BE_STREAM(p_out, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
@@ -81,9 +86,20 @@
p_len = p_out;
p_out += 1;
+ /* Account for data element header and length */
+ bytes_left -= 2;
+
/* Now, loop through and put in all the UUID(s) */
for (xx = 0; xx < num_uuids; xx++, p_uuid_list++) {
int len = p_uuid_list->GetShortestRepresentationSize();
+
+ if (len + 1 > bytes_left) {
+ DCHECK(0) << "SDP: Too many UUIDs for internal buffer";
+ break;
+ } else {
+ bytes_left -= (len + 1);
+ }
+
if (len == Uuid::kNumBytes16) {
UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES);
UINT16_TO_BE_STREAM(p_out, p_uuid_list->As16Bit());
@@ -120,6 +136,7 @@
uint8_t *p, *p_start, *p_param_len;
BT_HDR* p_cmd = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
uint16_t param_len;
+ uint16_t bytes_left = SDP_DATA_BUF_SIZE;
/* Prepare the buffer for sending the packet to L2CAP */
p_cmd->offset = L2CAP_MIN_OFFSET;
@@ -134,9 +151,24 @@
p_param_len = p;
p += 2;
-/* Build the UID sequence. */
+ /* Account for header size, max service record count and
+ * continuation state */
+ const uint16_t base_bytes = (sizeof(BT_HDR) + L2CAP_MIN_OFFSET +
+ 3u + /* service search request header */
+ 2u + /* param len */
+ 3u + ((p_cont) ? cont_len : 0));
+
+ if (base_bytes > bytes_left) {
+ DCHECK(0) << "SDP: Overran SDP data buffer";
+ osi_free(p_cmd);
+ return;
+ }
+
+ bytes_left -= base_bytes;
+
+ /* Build the UID sequence. */
p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
- p_ccb->p_db->uuid_filters);
+ p_ccb->p_db->uuid_filters, bytes_left);
/* Set max service record count */
UINT16_TO_BE_STREAM(p, sdp_cb.max_recs_per_search);
@@ -570,6 +602,7 @@
if ((cont_request_needed) || (!p_reply)) {
BT_HDR* p_msg = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
uint8_t* p;
+ uint16_t bytes_left = SDP_DATA_BUF_SIZE;
p_msg->offset = L2CAP_MIN_OFFSET;
p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
@@ -583,9 +616,24 @@
p_param_len = p;
p += 2;
-/* Build the UID sequence. */
+ /* Account for header size, max service record count and
+ * continuation state */
+ const uint16_t base_bytes = (sizeof(BT_HDR) + L2CAP_MIN_OFFSET +
+ 3u + /* service search request header */
+ 2u + /* param len */
+ 3u + /* max service record count */
+ ((p_reply) ? (*p_reply) : 0));
+
+ if (base_bytes > bytes_left) {
+ sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
+ return;
+ }
+
+ bytes_left -= base_bytes;
+
+ /* Build the UID sequence. */
p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
- p_ccb->p_db->uuid_filters);
+ p_ccb->p_db->uuid_filters, bytes_left);
/* Max attribute byte count */
UINT16_TO_BE_STREAM(p, sdp_cb.max_attr_list_size);