aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-05-10 16:21:08 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-05-10 16:21:08 +0000
commit7d62af68195b64ad8b05dcce1850248c216aeecd (patch)
tree08446834048956e58ac4488f38798864b857fcd2
parent24146d26f660a49bd7125adaa7affed2915cafcb (diff)
parent931089382491b193c052cda7cf3e0aa74763f17a (diff)
downloadbt-android10-android13-mainline-tzdata-release.tar.gz
Snap for 10101514 from 931089382491b193c052cda7cf3e0aa74763f17a to qt-aml-tzdata-releaseq_tzdata_aml_296200000android10-android13-mainline-tzdata-release
Change-Id: Icdc60af887aa20975c4668f4a75a5fab1aa977ac
-rw-r--r--bta/av/bta_av_act.cc16
-rw-r--r--btif/src/btif_hh.cc50
-rw-r--r--btif/src/btif_rc.cc52
-rw-r--r--stack/a2dp/a2dp_sbc.cc5
-rw-r--r--stack/avdt/avdt_scb_act.cc18
-rw-r--r--stack/btm/btm_acl.cc34
-rw-r--r--stack/btm/btm_ble.cc17
-rw-r--r--stack/btm/btm_ble_int.h3
-rw-r--r--stack/btm/btm_devctl.cc7
-rw-r--r--stack/btm/btm_int.h8
-rw-r--r--stack/btm/btm_sec.cc18
-rw-r--r--stack/btu/btu_hcif.cc12
-rw-r--r--stack/gatt/gatt_cl.cc5
-rw-r--r--stack/gatt/gatt_utils.cc7
-rw-r--r--stack/sdp/sdp_db.cc20
15 files changed, 219 insertions, 53 deletions
diff --git a/bta/av/bta_av_act.cc b/bta/av/bta_av_act.cc
index a7278420a..8809abed3 100644
--- a/bta/av/bta_av_act.cc
+++ b/bta/av/bta_av_act.cc
@@ -1848,7 +1848,21 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) {
if (p_lcb) {
rc_handle = bta_av_rc_create(p_cb, AVCT_INT,
(uint8_t)(p_scb->hdi + 1), p_lcb->lidx);
- p_cb->rcb[rc_handle].peer_features = peer_features;
+ if (rc_handle < BTA_AV_NUM_RCB) {
+ p_cb->rcb[rc_handle].peer_features = peer_features;
+ } else {
+ /* cannot create valid rc_handle for current device. report failure
+ */
+ APPL_TRACE_ERROR("%s: no link resources available", __func__);
+ p_scb->use_rc = false;
+ tBTA_AV_RC_OPEN rc_open;
+ rc_open.peer_addr = p_scb->PeerAddress();
+ rc_open.peer_features = 0;
+ rc_open.status = BTA_AV_FAIL_RESOURCES;
+ tBTA_AV bta_av_data;
+ bta_av_data.rc_open = rc_open;
+ (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data);
+ }
} else {
APPL_TRACE_ERROR("%s: can not find LCB!!", __func__);
}
diff --git a/btif/src/btif_hh.cc b/btif/src/btif_hh.cc
index 650923a3c..5c57ee80c 100644
--- a/btif/src/btif_hh.cc
+++ b/btif/src/btif_hh.cc
@@ -1098,6 +1098,38 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
/*******************************************************************************
*
+ * Function btif_hh_hsdata_rpt_copy_cb
+ *
+ * Description Deep copies the tBTA_HH_HSDATA structure
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+
+static void btif_hh_hsdata_rpt_copy_cb(uint16_t event, char* p_dest,
+ char* p_src) {
+ tBTA_HH_HSDATA* p_dst_data = (tBTA_HH_HSDATA*)p_dest;
+ tBTA_HH_HSDATA* p_src_data = (tBTA_HH_HSDATA*)p_src;
+ BT_HDR* hdr;
+
+ if (!p_src) {
+ BTIF_TRACE_ERROR("%s: Nothing to copy", __func__);
+ return;
+ }
+
+ memcpy(p_dst_data, p_src_data, sizeof(tBTA_HH_HSDATA));
+
+ hdr = p_src_data->rsp_data.p_rpt_data;
+ if (hdr != NULL) {
+ uint8_t* p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HH_HSDATA);
+ memcpy(p_data, hdr, BT_HDR_SIZE + hdr->offset + hdr->len);
+
+ p_dst_data->rsp_data.p_rpt_data = (BT_HDR*)p_data;
+ }
+}
+
+/*******************************************************************************
+ *
* Function bte_hh_evt
*
* Description Switches context from BTE to BTIF for all HH events
@@ -1109,6 +1141,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
bt_status_t status;
int param_len = 0;
+ tBTIF_COPY_CBACK* p_copy_cback = NULL;
if (BTA_HH_ENABLE_EVT == event)
param_len = sizeof(tBTA_HH_STATUS);
@@ -1120,11 +1153,18 @@ void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
param_len = sizeof(tBTA_HH_CBDATA);
else if (BTA_HH_GET_DSCP_EVT == event)
param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
- else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event) ||
- (BTA_HH_GET_IDLE_EVT == event))
+ else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_IDLE_EVT == event))
+ param_len = sizeof(tBTA_HH_HSDATA);
+ else if (BTA_HH_GET_RPT_EVT == event) {
+ BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
param_len = sizeof(tBTA_HH_HSDATA);
- else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
- (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
+
+ if (hdr != NULL) {
+ p_copy_cback = btif_hh_hsdata_rpt_copy_cb;
+ param_len += BT_HDR_SIZE + hdr->offset + hdr->len;
+ }
+ } else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
+ (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
param_len = sizeof(tBTA_HH_CBDATA);
else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
param_len = sizeof(tBTA_HH_DEV_INFO);
@@ -1133,7 +1173,7 @@ void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
/* switch context to btif task context (copy full union size for convenience)
*/
status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
- (char*)p_data, param_len, NULL);
+ (char*)p_data, param_len, p_copy_cback);
/* catch any failed context transfers */
ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc
index 575d83e37..61735f8b0 100644
--- a/btif/src/btif_rc.cc
+++ b/btif/src/btif_rc.cc
@@ -3541,29 +3541,31 @@ static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
* for standard attributes.
*/
p_app_settings->num_ext_attrs = 0;
- for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
+ for (xx = 0;
+ xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE;
+ xx++) {
osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
}
p_app_settings->ext_attr_index = 0;
- if (p_dev) {
- for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
- attrs[xx] = p_app_settings->attrs[xx].attr_id;
- }
-
- do_in_jni_thread(
- FROM_HERE,
- base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
- p_dev->rc_addr, p_app_settings->num_attrs,
- p_app_settings->attrs, 0, nullptr));
- get_player_app_setting_cmd(xx, attrs, p_dev);
+ for (xx = 0; xx < p_app_settings->num_attrs && xx < AVRC_MAX_APP_ATTR_SIZE;
+ xx++) {
+ attrs[xx] = p_app_settings->attrs[xx].attr_id;
}
+
+ do_in_jni_thread(
+ FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
+ p_dev->rc_addr, p_app_settings->num_attrs,
+ p_app_settings->attrs, 0, nullptr));
+ get_player_app_setting_cmd(xx, attrs, p_dev);
+
return;
}
for (xx = 0; xx < p_rsp->num_attr; xx++) {
uint8_t x;
- for (x = 0; x < p_app_settings->num_ext_attrs; x++) {
+ for (x = 0; x < p_app_settings->num_ext_attrs && x < AVRC_MAX_APP_ATTR_SIZE;
+ x++) {
if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id) {
p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
@@ -3573,7 +3575,9 @@ static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
}
}
- for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++) {
+ for (xx = 0;
+ xx < p_app_settings->ext_attrs[0].num_val && xx < BTRC_MAX_APP_ATTR_SIZE;
+ xx++) {
vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
}
get_player_app_setting_value_text_cmd(vals, xx, p_dev);
@@ -3617,11 +3621,13 @@ static void handle_app_attr_val_txt_response(
* for standard attributes.
*/
p_app_settings->num_ext_attrs = 0;
- for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
+ for (xx = 0;
+ xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE;
+ xx++) {
int x;
btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
- for (x = 0; x < p_ext_attr->num_val; x++)
+ for (x = 0; x < p_ext_attr->num_val && x < BTRC_MAX_APP_ATTR_SIZE; x++)
osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
p_ext_attr->num_val = 0;
osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
@@ -3640,11 +3646,17 @@ static void handle_app_attr_val_txt_response(
return;
}
+ if (p_app_settings->ext_val_index >= AVRC_MAX_APP_ATTR_SIZE) {
+ BTIF_TRACE_ERROR("ext_val_index is 0x%02x, overflow!",
+ p_app_settings->ext_val_index);
+ return;
+ }
+
for (xx = 0; xx < p_rsp->num_attr; xx++) {
uint8_t x;
btrc_player_app_ext_attr_t* p_ext_attr;
p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
- for (x = 0; x < p_rsp->num_attr; x++) {
+ for (x = 0; x < p_rsp->num_attr && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id) {
p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
@@ -3697,10 +3709,12 @@ static void handle_app_attr_val_txt_response(
**************************************************************************/
static void cleanup_app_attr_val_txt_response(
btif_rc_player_app_settings_t* p_app_settings) {
- for (uint8_t xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
+ for (uint8_t xx = 0;
+ xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE;
+ xx++) {
int x;
btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
- for (x = 0; x < p_ext_attr->num_val; x++) {
+ for (x = 0; x < p_ext_attr->num_val && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
}
p_ext_attr->num_val = 0;
diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc
index 4c48993c4..5036eec2e 100644
--- a/stack/a2dp/a2dp_sbc.cc
+++ b/stack/a2dp/a2dp_sbc.cc
@@ -704,6 +704,11 @@ bool A2DP_BuildCodecHeaderSbc(UNUSED_ATTR const uint8_t* p_codec_info,
BT_HDR* p_buf, uint16_t frames_per_packet) {
uint8_t* p;
+ // there is a timestamp right following p_buf
+ if (p_buf->offset < 4 + A2DP_SBC_MPL_HDR_LEN) {
+ return false;
+ }
+
p_buf->offset -= A2DP_SBC_MPL_HDR_LEN;
p = (uint8_t*)(p_buf + 1) + p_buf->offset;
p_buf->len += A2DP_SBC_MPL_HDR_LEN;
diff --git a/stack/avdt/avdt_scb_act.cc b/stack/avdt/avdt_scb_act.cc
index 31745bb2f..f2de4ba35 100644
--- a/stack/avdt/avdt_scb_act.cc
+++ b/stack/avdt/avdt_scb_act.cc
@@ -255,19 +255,24 @@ void avdt_scb_hdl_pkt_no_frag(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
if (offset > len) goto length_error;
p += 2;
BE_STREAM_TO_UINT16(ex_len, p);
- offset += ex_len * 4;
p += ex_len * 4;
}
+ if ((p - p_start) >= len) {
+ AVDT_TRACE_WARNING("%s: handling malformatted packet: ex_len too large", __func__);
+ osi_free_and_reset((void**)&p_data->p_pkt);
+ return;
+ }
+ offset = p - p_start;
+
/* adjust length for any padding at end of packet */
if (o_p) {
/* padding length in last byte of packet */
- pad_len = *(p_start + p_data->p_pkt->len);
+ pad_len = *(p_start + len - 1);
}
/* do sanity check */
- if ((offset > p_data->p_pkt->len) ||
- ((pad_len + offset) > p_data->p_pkt->len)) {
+ if (pad_len >= (len - offset)) {
AVDT_TRACE_WARNING("Got bad media packet");
osi_free_and_reset((void**)&p_data->p_pkt);
}
@@ -977,6 +982,11 @@ void avdt_scb_hdl_write_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
/* Build a media packet, and add an RTP header if required. */
if (add_rtp_header) {
+ if (p_data->apiwrite.p_buf->offset < AVDT_MEDIA_HDR_SIZE) {
+ android_errorWriteWithInfoLog(0x534e4554, "242535997", -1, NULL, 0);
+ return;
+ }
+
ssrc = avdt_scb_gen_ssrc(p_scb);
p_data->apiwrite.p_buf->len += AVDT_MEDIA_HDR_SIZE;
diff --git a/stack/btm/btm_acl.cc b/stack/btm/btm_acl.cc
index 55772e698..af0931965 100644
--- a/stack/btm/btm_acl.cc
+++ b/stack/btm/btm_acl.cc
@@ -2161,7 +2161,7 @@ void btm_read_tx_power_timeout(UNUSED_ATTR void* data) {
* Returns void
*
******************************************************************************/
-void btm_read_tx_power_complete(uint8_t* p, bool is_ble) {
+void btm_read_tx_power_complete(uint8_t* p, uint16_t evt_len, bool is_ble) {
tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_tx_power_cmpl_cb;
tBTM_TX_POWER_RESULT result;
tACL_CONN* p_acl_cb = &btm_cb.acl_db[0];
@@ -2172,6 +2172,10 @@ void btm_read_tx_power_complete(uint8_t* p, bool is_ble) {
/* If there was a registered callback, call it */
if (p_cb) {
+ if (evt_len < 1) {
+ goto err_out;
+ }
+
STREAM_TO_UINT8(result.hci_status, p);
if (result.hci_status == HCI_SUCCESS) {
@@ -2179,6 +2183,11 @@ void btm_read_tx_power_complete(uint8_t* p, bool is_ble) {
if (!is_ble) {
uint16_t handle;
+
+ if (evt_len < 4) {
+ goto err_out;
+ }
+
STREAM_TO_UINT16(handle, p);
STREAM_TO_UINT8(result.tx_power, p);
@@ -2190,6 +2199,10 @@ void btm_read_tx_power_complete(uint8_t* p, bool is_ble) {
}
}
} else {
+ if (evt_len < 2) {
+ goto err_out;
+ }
+
STREAM_TO_UINT8(result.tx_power, p);
result.rem_bda = btm_cb.devcb.read_tx_pwr_addr;
}
@@ -2201,6 +2214,11 @@ void btm_read_tx_power_complete(uint8_t* p, bool is_ble) {
(*p_cb)(&result);
}
+
+ return;
+
+ err_out:
+ BTM_TRACE_ERROR("%s: malformatted event packet, too short", __func__);
}
/*******************************************************************************
@@ -2230,7 +2248,7 @@ void btm_read_rssi_timeout(UNUSED_ATTR void* data) {
* Returns void
*
******************************************************************************/
-void btm_read_rssi_complete(uint8_t* p) {
+void btm_read_rssi_complete(uint8_t* p, uint16_t evt_len) {
tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_rssi_cmpl_cb;
tBTM_RSSI_RESULT result;
tACL_CONN* p_acl_cb = &btm_cb.acl_db[0];
@@ -2241,12 +2259,19 @@ void btm_read_rssi_complete(uint8_t* p) {
/* If there was a registered callback, call it */
if (p_cb) {
+ if (evt_len < 1) {
+ goto err_out;
+ }
STREAM_TO_UINT8(result.hci_status, p);
if (result.hci_status == HCI_SUCCESS) {
uint16_t handle;
result.status = BTM_SUCCESS;
+ if (evt_len < 4) {
+ goto err_out;
+ }
+
STREAM_TO_UINT16(handle, p);
STREAM_TO_UINT8(result.rssi, p);
@@ -2266,6 +2291,11 @@ void btm_read_rssi_complete(uint8_t* p) {
(*p_cb)(&result);
}
+
+ return;
+
+err_out:
+ BTM_TRACE_ERROR("%s: malformatted event packet, too short", __func__);
}
/*******************************************************************************
diff --git a/stack/btm/btm_ble.cc b/stack/btm/btm_ble.cc
index b1f4119d5..8aa4de8bd 100644
--- a/stack/btm/btm_ble.cc
+++ b/stack/btm/btm_ble.cc
@@ -1141,7 +1141,8 @@ tL2CAP_LE_RESULT_CODE btm_ble_start_sec_check(const RawAddress& bd_addr,
* Returns void
*
******************************************************************************/
-void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code,
+void btm_ble_rand_enc_complete(uint8_t* p, uint16_t evt_len,
+ uint16_t op_code,
tBTM_RAND_ENC_CB* p_enc_cplt_cback) {
tBTM_RAND_ENC params;
uint8_t* p_dest = params.param_buf;
@@ -1152,6 +1153,11 @@ void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code,
/* If there was a callback address for vcs complete, call it */
if (p_enc_cplt_cback && p) {
+
+ if (evt_len < 1) {
+ goto err_out;
+ }
+
/* Pass paramters to the callback function */
STREAM_TO_UINT8(params.status, p); /* command status */
@@ -1163,12 +1169,21 @@ void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code,
else
params.param_len = OCTET16_LEN;
+ if (evt_len < 1 + params.param_len) {
+ goto err_out;
+ }
+
/* Fetch return info from HCI event message */
memcpy(p_dest, p, params.param_len);
}
if (p_enc_cplt_cback) /* Call the Encryption complete callback function */
(*p_enc_cplt_cback)(&params);
}
+
+ return;
+
+err_out:
+ BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__);
}
/*******************************************************************************
diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h
index fc1bfcf22..20985997a 100644
--- a/stack/btm/btm_ble_int.h
+++ b/stack/btm/btm_ble_int.h
@@ -103,7 +103,8 @@ extern bool btm_ble_get_enc_key_type(const RawAddress& bd_addr,
uint8_t* p_key_types);
extern void btm_ble_test_command_complete(uint8_t* p);
-extern void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code,
+extern void btm_ble_rand_enc_complete(uint8_t* p, uint16_t evt_len,
+ uint16_t op_code,
tBTM_RAND_ENC_CB* p_enc_cplt_cback);
extern void btm_sec_save_le_key(const RawAddress& bd_addr,
diff --git a/stack/btm/btm_devctl.cc b/stack/btm/btm_devctl.cc
index bc3fb5649..1600cce7d 100644
--- a/stack/btm/btm_devctl.cc
+++ b/stack/btm/btm_devctl.cc
@@ -829,7 +829,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(const RawAddress* bd_addr,
* Returns void
*
******************************************************************************/
-void btm_delete_stored_link_key_complete(uint8_t* p) {
+void btm_delete_stored_link_key_complete(uint8_t* p, uint16_t evt_len) {
tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_stored_link_key_cmpl_cb;
tBTM_DELETE_STORED_LINK_KEY_COMPLETE result;
@@ -840,6 +840,11 @@ void btm_delete_stored_link_key_complete(uint8_t* p) {
/* Set the call back event to indicate command complete */
result.event = BTM_CB_EVT_DELETE_STORED_LINK_KEYS;
+ if (evt_len < 3) {
+ BTM_TRACE_ERROR("%s: Bogus event packet, too short", __func__);
+ return;
+ }
+
/* Extract the result fields from the HCI event */
STREAM_TO_UINT8(result.status, p);
STREAM_TO_UINT16(result.num_keys, p);
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index 05180db5e..d68da0325 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -93,7 +93,7 @@ extern uint8_t btm_handle_to_acl_index(uint16_t hci_handle);
extern void btm_read_link_policy_complete(uint8_t* p);
extern void btm_read_rssi_timeout(void* data);
-extern void btm_read_rssi_complete(uint8_t* p);
+extern void btm_read_rssi_complete(uint8_t* p, uint16_t evt_len);
extern void btm_read_failed_contact_counter_timeout(void* data);
extern void btm_read_failed_contact_counter_complete(uint8_t* p);
@@ -102,7 +102,7 @@ extern void btm_read_automatic_flush_timeout_timeout(void* data);
extern void btm_read_automatic_flush_timeout_complete(uint8_t* p);
extern void btm_read_tx_power_timeout(void* data);
-extern void btm_read_tx_power_complete(uint8_t* p, bool is_ble);
+extern void btm_read_tx_power_complete(uint8_t* p, uint16_t evt_len, bool is_ble);
extern void btm_read_link_quality_timeout(void* data);
extern void btm_read_link_quality_complete(uint8_t* p);
@@ -191,7 +191,7 @@ extern void btm_vsc_complete(uint8_t* p, uint16_t cc_opcode, uint16_t evt_len,
tBTM_VSC_CMPL_CB* p_vsc_cplt_cback);
extern void btm_inq_db_reset(void);
extern void btm_vendor_specific_evt(uint8_t* p, uint8_t evt_len);
-extern void btm_delete_stored_link_key_complete(uint8_t* p);
+extern void btm_delete_stored_link_key_complete(uint8_t* p, uint16_t evt_len);
extern void btm_report_device_status(tBTM_DEV_STATUS status);
extern tBTM_STATUS BTM_BT_Quality_Report_VSE_Register(
bool is_register, tBTM_BT_QUALITY_REPORT_RECEIVER* p_bqr_report_receiver);
@@ -276,7 +276,7 @@ extern tL2CAP_LE_RESULT_CODE btm_ble_start_sec_check(
extern tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda);
extern void btm_rem_oob_req(uint8_t* p);
-extern void btm_read_local_oob_complete(uint8_t* p);
+extern void btm_read_local_oob_complete(uint8_t* p, uint16_t evt_len);
extern void btm_acl_resubmit_page(void);
extern void btm_acl_reset_paging(void);
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 277e01dc1..efc904a86 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -3664,13 +3664,22 @@ void btm_rem_oob_req(uint8_t* p) {
* Returns void
*
******************************************************************************/
-void btm_read_local_oob_complete(uint8_t* p) {
+void btm_read_local_oob_complete(uint8_t* p, uint16_t evt_len) {
tBTM_SP_LOC_OOB evt_data;
- uint8_t status = *p++;
+ uint8_t status;
+ if (evt_len < 1) {
+ goto err_out;
+ }
+ STREAM_TO_UINT8(status, p);
BTM_TRACE_EVENT("btm_read_local_oob_complete:%d", status);
if (status == HCI_SUCCESS) {
evt_data.status = BTM_SUCCESS;
+
+ if (evt_len < 1 + 32) {
+ goto err_out;
+ }
+
STREAM_TO_ARRAY16(evt_data.c.data(), p);
STREAM_TO_ARRAY16(evt_data.r.data(), p);
} else
@@ -3681,6 +3690,11 @@ void btm_read_local_oob_complete(uint8_t* p) {
btm_sp_evt_data.loc_oob = evt_data;
(*btm_cb.api.p_sp_callback)(BTM_SP_LOC_OOB_EVT, &btm_sp_evt_data);
}
+
+ return;
+
+err_out:
+ BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__);
}
/*******************************************************************************
diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc
index 52d5d60f8..931e68467 100644
--- a/stack/btu/btu_hcif.cc
+++ b/stack/btu/btu_hcif.cc
@@ -1368,7 +1368,7 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p,
break;
case HCI_DELETE_STORED_LINK_KEY:
- btm_delete_stored_link_key_complete(p);
+ btm_delete_stored_link_key_complete(p, evt_len);
break;
case HCI_READ_LOCAL_NAME:
@@ -1380,7 +1380,7 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p,
break;
case HCI_READ_RSSI:
- btm_read_rssi_complete(p);
+ btm_read_rssi_complete(p, evt_len);
break;
case HCI_READ_FAILED_CONTACT_COUNTER:
@@ -1392,7 +1392,7 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p,
break;
case HCI_READ_TRANSMIT_POWER_LEVEL:
- btm_read_tx_power_complete(p, false);
+ btm_read_tx_power_complete(p, evt_len, false);
break;
case HCI_CREATE_CONNECTION_CANCEL:
@@ -1400,7 +1400,7 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p,
break;
case HCI_READ_LOCAL_OOB_DATA:
- btm_read_local_oob_complete(p);
+ btm_read_local_oob_complete(p, evt_len);
break;
case HCI_READ_INQ_TX_POWER_LEVEL:
@@ -1410,11 +1410,11 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p,
/* BLE Commands sComplete*/
case HCI_BLE_RAND:
case HCI_BLE_ENCRYPT:
- btm_ble_rand_enc_complete(p, opcode, (tBTM_RAND_ENC_CB*)p_cplt_cback);
+ btm_ble_rand_enc_complete(p, evt_len, opcode, (tBTM_RAND_ENC_CB*)p_cplt_cback);
break;
case HCI_BLE_READ_ADV_CHNL_TX_POWER:
- btm_read_tx_power_complete(p, true);
+ btm_read_tx_power_complete(p, evt_len, true);
break;
case HCI_BLE_WRITE_ADV_ENABLE:
diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc
index 3115317da..db41c5f9f 100644
--- a/stack/gatt/gatt_cl.cc
+++ b/stack/gatt/gatt_cl.cc
@@ -572,7 +572,8 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
LOG(ERROR) << StringPrintf("value resp op_code = %s len = %d",
gatt_dbg_op_name(op_code), len);
- if (len < GATT_PREP_WRITE_RSP_MIN_LEN) {
+ if (len < GATT_PREP_WRITE_RSP_MIN_LEN ||
+ len > GATT_PREP_WRITE_RSP_MIN_LEN + sizeof(value.value)) {
LOG(ERROR) << "illegal prepare write response length, discard";
gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
return;
@@ -581,7 +582,7 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
STREAM_TO_UINT16(value.handle, p);
STREAM_TO_UINT16(value.offset, p);
- value.len = len - 4;
+ value.len = len - GATT_PREP_WRITE_RSP_MIN_LEN;
memcpy(value.value, p, value.len);
diff --git a/stack/gatt/gatt_utils.cc b/stack/gatt/gatt_utils.cc
index 2bd424000..013011778 100644
--- a/stack/gatt/gatt_utils.cc
+++ b/stack/gatt/gatt_utils.cc
@@ -1198,6 +1198,13 @@ void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, void* p_data) {
cb_data.att_value.handle = p_clcb->s_handle;
cb_data.att_value.len = p_clcb->counter;
+ if (cb_data.att_value.len > GATT_MAX_ATTR_LEN) {
+ LOG(WARNING) << __func__
+ << StringPrintf(" Large cb_data.att_value, size=%d",
+ cb_data.att_value.len);
+ cb_data.att_value.len = GATT_MAX_ATTR_LEN;
+ }
+
if (p_data && p_clcb->counter)
memcpy(cb_data.att_value.value, p_data, cb_data.att_value.len);
}
diff --git a/stack/sdp/sdp_db.cc b/stack/sdp/sdp_db.cc
index ea5b84d23..4130ae71a 100644
--- a/stack/sdp/sdp_db.cc
+++ b/stack/sdp/sdp_db.cc
@@ -362,6 +362,11 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
uint16_t xx, yy, zz;
tSDP_RECORD* p_rec = &sdp_cb.server_db.record[0];
+ if (p_val == nullptr) {
+ SDP_TRACE_WARNING("Trying to add attribute with p_val == nullptr, skipped");
+ return (false);
+ }
+
if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) {
if ((attr_type == UINT_DESC_TYPE) ||
(attr_type == TWO_COMP_INT_DESC_TYPE) ||
@@ -398,6 +403,13 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
if (p_rec->record_handle == handle) {
tSDP_ATTRIBUTE* p_attr = &p_rec->attribute[0];
+ // error out early, no need to look up
+ if (p_rec->free_pad_ptr >= SDP_MAX_PAD_LEN) {
+ SDP_TRACE_ERROR("the free pad for SDP record with handle %d is "
+ "full, skip adding the attribute", handle);
+ return (false);
+ }
+
/* Found the record. Now, see if the attribute already exists */
for (xx = 0; xx < p_rec->num_attributes; xx++, p_attr++) {
/* The attribute exists. replace it */
@@ -437,15 +449,13 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
attr_len = 0;
}
- if ((attr_len > 0) && (p_val != 0)) {
+ if (attr_len > 0) {
p_attr->len = attr_len;
memcpy(&p_rec->attr_pad[p_rec->free_pad_ptr], p_val, (size_t)attr_len);
p_attr->value_ptr = &p_rec->attr_pad[p_rec->free_pad_ptr];
p_rec->free_pad_ptr += attr_len;
- } else if ((attr_len == 0 &&
- p_attr->len !=
- 0) || /* if truncate to 0 length, simply don't add */
- p_val == 0) {
+ } else if (attr_len == 0 && p_attr->len != 0) {
+ /* if truncate to 0 length, simply don't add */
SDP_TRACE_ERROR(
"SDP_AddAttribute fail, length exceed maximum: ID %d: attr_len:%d ",
attr_id, attr_len);