aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-02-08 04:16:34 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-02-08 04:16:34 +0000
commit248e8f4468a002c503cc4a5aaf2a1a1510cf59b0 (patch)
tree447f1e05b2304f8c2eb2c0dca31193b512a14619
parent83c8be063854a84843042a2089f63e77777f18e8 (diff)
parent72b1cebaa9cc7ace841d887f0d4a4bf6daccde6e (diff)
downloadbt-248e8f4468a002c503cc4a5aaf2a1a1510cf59b0.tar.gz
Merge cherrypicks of [3581037, 3581038, 3580473, 3580624, 3580656, 3580657, 3580658, 3580382, 3580474, 3580475, 3581039, 3581040, 3580476, 3580206, 3581527, 3580955, 3580956, 3580957, 3580958, 3580959, 3580960, 3580961, 3580962, 3580963, 3580964, 3580965, 3580966, 3581567, 3581568, 3581569, 3581570, 3581571, 3580625, 3580626, 3581587, 3581513, 3581514, 3581515, 3580477, 3581588, 3580659, 3580660, 3580383, 3580384, 3580478, 3580719, 3580479, 3580480, 3581385, 3581528, 3581041, 3581042, 3581043, 3581044, 3581045, 3581046, 3581607, 3580385, 3580481, 3580482, 3580483, 3580661, 3580662, 3580663, 3580664, 3580665, 3580484, 3580485, 3581608, 3581609, 3581610, 3581611, 3581612, 3581589, 3581613, 3580486, 3581519, 3581627, 3581628, 3581529, 3581530, 3581531, 3581629, 3581630] into oc-mr1-release
Change-Id: Idad72f8100382bf89a70f797f55169262d619791
-rw-r--r--stack/sdp/sdp_server.cc60
-rw-r--r--stack/sdp/sdp_utils.cc38
2 files changed, 71 insertions, 27 deletions
diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc
index b18f42959..e4ed60a92 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -24,7 +24,6 @@
******************************************************************************/
#include <cutils/log.h>
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -54,7 +53,7 @@
/******************************************************************************/
static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
- UNUSED_ATTR uint8_t* p_req_end);
+ uint8_t* p_req_end);
static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
@@ -62,7 +61,7 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
- UNUSED_ATTR uint8_t* p_req_end);
+ uint8_t* p_req_end);
/******************************************************************************/
/* E R R O R T E X T S T R I N G S */
@@ -123,11 +122,25 @@ void sdp_server_handle_client_req(tCONN_CB* p_ccb, BT_HDR* p_msg) {
alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
sdp_conn_timer_timeout, p_ccb);
+ if (p_req + sizeof(pdu_id) + sizeof(trans_num) > p_req_end) {
+ android_errorWriteLog(0x534e4554, "69384124");
+ trans_num = 0;
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
+ SDP_TEXT_BAD_HEADER);
+ }
+
/* The first byte in the message is the pdu type */
pdu_id = *p_req++;
/* Extract the transaction number and parameter length */
BE_STREAM_TO_UINT16(trans_num, p_req);
+
+ if (p_req + sizeof(param_len) > p_req_end) {
+ android_errorWriteLog(0x534e4554, "69384124");
+ sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
+ SDP_TEXT_BAD_HEADER);
+ }
+
BE_STREAM_TO_UINT16(param_len, p_req);
if ((p_req + param_len) != p_req_end) {
@@ -171,7 +184,7 @@ void sdp_server_handle_client_req(tCONN_CB* p_ccb, BT_HDR* p_msg) {
******************************************************************************/
static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
- UNUSED_ATTR uint8_t* p_req_end) {
+ uint8_t* p_req_end) {
uint16_t max_replies, cur_handles, rem_handles, cont_offset;
tSDP_UUID_SEQ uid_seq;
uint8_t *p_rsp, *p_rsp_start, *p_rsp_param_len;
@@ -189,15 +202,15 @@ static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
}
/* Get the max replies we can send. Cap it at our max anyways. */
- BE_STREAM_TO_UINT16(max_replies, p_req);
-
- if (max_replies > SDP_MAX_RECORDS) max_replies = SDP_MAX_RECORDS;
-
- if ((!p_req) || (p_req > p_req_end)) {
+ if (p_req + sizeof(max_replies) + sizeof(uint8_t) > p_req_end) {
+ android_errorWriteLog(0x534e4554, "69384124");
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
SDP_TEXT_BAD_MAX_RECORDS_LIST);
return;
}
+ BE_STREAM_TO_UINT16(max_replies, p_req);
+
+ if (max_replies > SDP_MAX_RECORDS) max_replies = SDP_MAX_RECORDS;
/* Get a list of handles that match the UUIDs given to us */
for (num_rsp_handles = 0; num_rsp_handles < max_replies;) {
@@ -211,7 +224,8 @@ static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num,
/* Check if this is a continuation request */
if (*p_req) {
- if (*p_req++ != SDP_CONTINUATION_LEN || (p_req >= p_req_end)) {
+ if (*p_req++ != SDP_CONTINUATION_LEN ||
+ (p_req + sizeof(cont_offset) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
SDP_TEXT_BAD_CONT_LEN);
return;
@@ -310,15 +324,16 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
bool is_cont = false;
uint16_t attr_len;
- /* Extract the record handle */
- BE_STREAM_TO_UINT32(rec_handle, p_req);
-
- if (p_req > p_req_end) {
+ if (p_req + sizeof(rec_handle) + sizeof(max_list_len) > p_req_end) {
+ android_errorWriteLog(0x534e4554, "69384124");
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_SERV_REC_HDL,
SDP_TEXT_BAD_HANDLE);
return;
}
+ /* Extract the record handle */
+ BE_STREAM_TO_UINT32(rec_handle, p_req);
+
/* Get the max list length we can send. Cap it at MTU size minus overhead */
BE_STREAM_TO_UINT16(max_list_len, p_req);
@@ -327,7 +342,8 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
- if ((!p_req) || (!attr_seq.num_attr) || (p_req > p_req_end)) {
+ if ((!p_req) || (!attr_seq.num_attr) ||
+ (p_req + sizeof(uint8_t) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
SDP_TEXT_BAD_ATTR_LIST);
return;
@@ -355,7 +371,8 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
/* Check if this is a continuation request */
if (*p_req) {
- if (*p_req++ != SDP_CONTINUATION_LEN) {
+ if (*p_req++ != SDP_CONTINUATION_LEN ||
+ (p_req + sizeof(cont_offset) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
SDP_TEXT_BAD_CONT_LEN);
return;
@@ -520,7 +537,7 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
******************************************************************************/
static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
uint16_t param_len, uint8_t* p_req,
- UNUSED_ATTR uint8_t* p_req_end) {
+ uint8_t* p_req_end) {
uint16_t max_list_len;
int16_t rem_len;
uint16_t len_to_send, cont_offset;
@@ -537,7 +554,8 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
/* Extract the UUID sequence to search for */
p_req = sdpu_extract_uid_seq(p_req, param_len, &uid_seq);
- if ((!p_req) || (!uid_seq.num_uids)) {
+ if ((!p_req) || (!uid_seq.num_uids) ||
+ (p_req + sizeof(uint16_t) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
SDP_TEXT_BAD_UUID_LIST);
return;
@@ -551,7 +569,8 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
p_req = sdpu_extract_attr_seq(p_req, param_len, &attr_seq);
- if ((!p_req) || (!attr_seq.num_attr)) {
+ if ((!p_req) || (!attr_seq.num_attr) ||
+ (p_req + sizeof(uint8_t) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
SDP_TEXT_BAD_ATTR_LIST);
return;
@@ -571,7 +590,8 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num,
/* Check if this is a continuation request */
if (*p_req) {
- if (*p_req++ != SDP_CONTINUATION_LEN) {
+ if (*p_req++ != SDP_CONTINUATION_LEN ||
+ (p_req + sizeof(uint16_t) > p_req_end)) {
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE,
SDP_TEXT_BAD_CONT_LEN);
return;
diff --git a/stack/sdp/sdp_utils.cc b/stack/sdp/sdp_utils.cc
index 803e963c2..e6589d403 100644
--- a/stack/sdp/sdp_utils.cc
+++ b/stack/sdp/sdp_utils.cc
@@ -332,6 +332,8 @@ uint8_t* sdpu_extract_uid_seq(uint8_t* p, uint16_t param_len,
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;
@@ -350,19 +352,25 @@ uint8_t* sdpu_extract_uid_seq(uint8_t* p, uint16_t param_len,
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) return (NULL);
+ if (seq_len > param_len) return (NULL);
p_seq_end = p + seq_len;
@@ -385,12 +393,15 @@ uint8_t* sdpu_extract_uid_seq(uint8_t* p, uint16_t param_len,
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:
@@ -398,7 +409,8 @@ uint8_t* sdpu_extract_uid_seq(uint8_t* p, uint16_t param_len,
}
/* 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_t)uuid_len;
BE_STREAM_TO_ARRAY(p, p_seq->uuid_entry[p_seq->num_uids].value,
(int)uuid_len);
@@ -435,30 +447,38 @@ uint8_t* sdpu_extract_attr_seq(uint8_t* p, uint16_t param_len,
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);
+ if (type != DATA_ELE_SEQ_DESC_TYPE) 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);
+ if (list_len > param_len) return NULL;
p_end_list = p + list_len;
@@ -468,7 +488,7 @@ uint8_t* sdpu_extract_attr_seq(uint8_t* p, uint16_t param_len,
type = descr >> 3;
size = descr & 7;
- if (type != UINT_DESC_TYPE) return (p);
+ if (type != UINT_DESC_TYPE) return NULL;
switch (size) {
case SIZE_TWO_BYTES:
@@ -478,20 +498,24 @@ uint8_t* sdpu_extract_attr_seq(uint8_t* p, uint16_t param_len,
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);
p_seq->attr_entry[p_seq->num_attr].end =