Loading system/stack/gatt/gatt_sr.cc +17 −15 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ * this file contains the GATT server functions * ******************************************************************************/ #include <algorithm> #include <string.h> #include "bt_target.h" Loading Loading @@ -195,37 +196,38 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) { } if (p_rsp != NULL) { total_len = (p_buf->len + p_rsp->attr_value.len); total_len = p_buf->len; if (p_cmd->multi_req.variable_len) { total_len += 2; } if (total_len > mtu) { /* just send the partial response for the overflow case */ len = p_rsp->attr_value.len - (total_len - mtu); VLOG(1) << "Buffer space not enough for this data item, skipping"; break; } len = std::min((size_t) p_rsp->attr_value.len, mtu - total_len); if (len == 0) { VLOG(1) << "Buffer space not enough for this data item, skipping"; break; } if (len < p_rsp->attr_value.len) { is_overflow = true; VLOG(1) << StringPrintf( "multi read overflow available len=%zu val_len=%d", len, p_rsp->attr_value.len); } else { len = p_rsp->attr_value.len; } if (p_cmd->multi_req.variable_len) { UINT16_TO_STREAM(p, len); UINT16_TO_STREAM(p, (uint16_t) len); p_buf->len += 2; } if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) { // check for possible integer overflow if (p_buf->len + len <= UINT16_MAX) { memcpy(p, p_rsp->attr_value.value, len); if (!is_overflow) p += len; p_buf->len += len; } else { p_cmd->status = GATT_NOT_FOUND; break; } ARRAY_TO_STREAM(p, p_rsp->attr_value.value, (uint16_t) len); p_buf->len += (uint16_t) len; } else { p_cmd->status = GATT_NOT_FOUND; break; Loading system/stack/sdp/sdp_discovery.cc +53 −5 Original line number Diff line number Diff line Loading @@ -70,10 +70,15 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, * ******************************************************************************/ 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); Loading @@ -81,9 +86,20 @@ static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids, 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()); Loading Loading @@ -120,6 +136,7 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len, 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; Loading @@ -134,9 +151,24 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len, p_param_len = p; p += 2; /* 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); Loading Loading @@ -562,6 +594,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, 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; Loading @@ -575,9 +608,24 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, p_param_len = p; p += 2; /* 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); Loading Loading
system/stack/gatt/gatt_sr.cc +17 −15 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ * this file contains the GATT server functions * ******************************************************************************/ #include <algorithm> #include <string.h> #include "bt_target.h" Loading Loading @@ -195,37 +196,38 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) { } if (p_rsp != NULL) { total_len = (p_buf->len + p_rsp->attr_value.len); total_len = p_buf->len; if (p_cmd->multi_req.variable_len) { total_len += 2; } if (total_len > mtu) { /* just send the partial response for the overflow case */ len = p_rsp->attr_value.len - (total_len - mtu); VLOG(1) << "Buffer space not enough for this data item, skipping"; break; } len = std::min((size_t) p_rsp->attr_value.len, mtu - total_len); if (len == 0) { VLOG(1) << "Buffer space not enough for this data item, skipping"; break; } if (len < p_rsp->attr_value.len) { is_overflow = true; VLOG(1) << StringPrintf( "multi read overflow available len=%zu val_len=%d", len, p_rsp->attr_value.len); } else { len = p_rsp->attr_value.len; } if (p_cmd->multi_req.variable_len) { UINT16_TO_STREAM(p, len); UINT16_TO_STREAM(p, (uint16_t) len); p_buf->len += 2; } if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) { // check for possible integer overflow if (p_buf->len + len <= UINT16_MAX) { memcpy(p, p_rsp->attr_value.value, len); if (!is_overflow) p += len; p_buf->len += len; } else { p_cmd->status = GATT_NOT_FOUND; break; } ARRAY_TO_STREAM(p, p_rsp->attr_value.value, (uint16_t) len); p_buf->len += (uint16_t) len; } else { p_cmd->status = GATT_NOT_FOUND; break; Loading
system/stack/sdp/sdp_discovery.cc +53 −5 Original line number Diff line number Diff line Loading @@ -70,10 +70,15 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, * ******************************************************************************/ 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); Loading @@ -81,9 +86,20 @@ static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids, 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()); Loading Loading @@ -120,6 +136,7 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len, 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; Loading @@ -134,9 +151,24 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len, p_param_len = p; p += 2; /* 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); Loading Loading @@ -562,6 +594,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, 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; Loading @@ -575,9 +608,24 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, p_param_len = p; p += 2; /* 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); Loading