diff --git a/components/bt/host/bluedroid/bta/av/bta_av_aact.c b/components/bt/host/bluedroid/bta/av/bta_av_aact.c index 9564f6a217..0c973c496e 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_aact.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_aact.c @@ -1937,13 +1937,17 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) void bta_av_setconfig_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) { tBTA_AV_REJECT reject; - UINT8 avdt_handle = p_data->ci_setconfig.avdt_handle; + UINT8 err_code = p_data->ci_setconfig.err_code; - bta_av_adjust_seps_idx(p_scb, avdt_handle); + if (err_code == AVDT_SUCCESS) { + err_code = AVDT_ERR_UNSUP_CFG; + } + + bta_av_adjust_seps_idx(p_scb, p_scb->avdt_handle); APPL_TRACE_DEBUG("bta_av_setconfig_rej: sep_idx: %d", p_scb->sep_idx); - AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, p_data->ci_setconfig.err_code, 0); + AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, err_code, 0); - bdcpy(reject.bd_addr, p_data->str_msg.bd_addr); + bdcpy(reject.bd_addr, p_scb->peer_addr); reject.hndl = p_scb->hndl; (*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, (tBTA_AV *) &reject); } diff --git a/components/bt/host/bluedroid/bta/av/bta_av_act.c b/components/bt/host/bluedroid/bta/av/bta_av_act.c index bdfb29d295..943f376d56 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_act.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_act.c @@ -1184,16 +1184,16 @@ void bta_av_conn_chg(tBTA_AV_DATA *p_data) } } } else { - if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) { - bta_sys_conn_close(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr); - /* this channel is still marked as open. decrease the count */ - bta_av_cb.audio_open_cnt--; - } - - /* clear the conned mask for this channel */ - p_cb->conn_audio &= ~mask; - p_cb->conn_video &= ~mask; if (p_scb) { + if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) { + bta_sys_conn_close(TSEP_TO_SYS_ID(p_scb->seps[p_scb->sep_idx].tsep), bta_av_cb.audio_open_cnt, p_scb->peer_addr); + /* this channel is still marked as open. decrease the count */ + bta_av_cb.audio_open_cnt--; + } + /* clear the conned mask for this channel */ + p_cb->conn_audio &= ~mask; + p_cb->conn_video &= ~mask; + /* the stream is closed. * clear the peer address, so it would not mess up the AVRCP for the next round of operation */ bdcpy(p_scb->peer_addr, bd_addr_null); @@ -1629,9 +1629,20 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data) p_lcb = bta_av_find_lcb(p_scb->peer_addr, BTA_AV_LCB_FIND); if (p_lcb) { rc_handle = bta_av_rc_create(p_cb, AVCT_INT, (UINT8)(p_scb->hdi + 1), p_lcb->lidx); - p_cb->rcb[rc_handle].peer_features = peer_features; - p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features; - p_cb->rcb[rc_handle].peer_tg_features = peer_tg_features; + if (rc_handle < BTA_AV_NUM_RCB) { + p_cb->rcb[rc_handle].peer_features = peer_features; + p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features; + p_cb->rcb[rc_handle].peer_tg_features = peer_tg_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; + bdcpy(rc_open.peer_addr, p_scb->peer_addr); + rc_open.peer_features = 0; + rc_open.sdp_disc_done = FALSE; + rc_open.status = BTA_AV_FAIL_SDP; + (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open); + } } #if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE) else { diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index dbe5d574ce..818b7075cd 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -2248,7 +2248,7 @@ void bta_dm_search_result (tBTA_DM_MSG *p_data) /* call back if application wants name discovery or found services that application is searching */ if (( !bta_dm_search_cb.services ) - || (( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services ))) { + || ( p_data->disc_result.result.disc_res.services )) { bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result); } diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index cef006064e..b7018d32c7 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -2028,7 +2028,7 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id, if ( ++ p_srcb->update_count == bta_gattc_num_reg_app()) { /* not an opened connection; or connection busy */ /* search for first available clcb and start discovery */ - if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) { + if ((p_clcb == NULL) || (p_clcb->p_q_cmd != NULL)) { for (i = 0 ; i < BTA_GATTC_CLCB_MAX; i ++) { if (bta_gattc_cb.clcb[i].in_use && bta_gattc_cb.clcb[i].p_srcb == p_srcb && diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c index 661d237266..fe494ff3a1 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c @@ -1370,14 +1370,8 @@ BOOLEAN bta_ag_sco_is_open(tBTA_AG_SCB *p_scb) *******************************************************************************/ BOOLEAN bta_ag_sco_is_opening(tBTA_AG_SCB *p_scb) { -#if (BTM_WBS_INCLUDED == TRUE ) - return (((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) || - (bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST)) && - (bta_ag_cb.sco.p_curr_scb == p_scb)); -#else return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) && (bta_ag_cb.sco.p_curr_scb == p_scb)); -#endif } /******************************************************************************* @@ -1665,7 +1659,7 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST || bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST) { - /* If script overrided sco parameter by BTA_CMD_SET_ESCO_PARAM */ + /* If script overrode sco parameter by BTA_CMD_SET_ESCO_PARAM */ if (bta_ag_cb.sco.param_updated) { resp = bta_ag_cb.sco.params; @@ -1736,7 +1730,7 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data ** ** Function bta_ag_ci_sco_data ** -** Description Process the SCO data ready callin event +** Description Process the SCO data ready call in event ** ** ** Returns void diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c index d35ad4f7c1..0b02557b08 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c @@ -404,6 +404,11 @@ void bta_ag_do_disc(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK service) return; } + if (p_scb->p_disc_db) { + APPL_TRACE_ERROR("Discovery already in progress... returning."); + return; + } + /* allocate buffer for sdp database */ p_scb->p_disc_db = (tSDP_DISCOVERY_DB *) osi_malloc(BTA_AG_DISC_BUF_SIZE); if(p_scb->p_disc_db) { diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_at.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_at.c index adf3d609d0..169c14dfbf 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_at.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_at.c @@ -362,6 +362,10 @@ static void bta_hf_client_handle_cind_list_item(char *name, UINT32 min, UINT32 m APPL_TRACE_DEBUG("%s %u.%s <%u:%u>", __FUNCTION__, index, name, min, max); + if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) { + return; + } + /* look for a matching indicator on list of supported ones */ for (i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++) { if (strcmp(name, BTA_HF_CLIENT_INDICATOR_SERVICE) == 0) { @@ -591,7 +595,7 @@ while (*buf == ' ') buf++; buf += sizeof("\r\n") - 1; /* skip rest of AT string up to */ -#define AT_SKIP_REST(buf) while(*buf != '\r') buf++; +#define AT_SKIP_REST(buf) while((*buf != '\r') && (*buf != '\0')) buf++; static char *bta_hf_client_parse_ok(char *buffer) { @@ -1018,7 +1022,7 @@ static char *bta_hf_client_parse_clcc(char *buffer) } } - /* Skip any remaing param,as they are not defined by BT HFP spec */ + /* Skip any remaining param,as they are not defined by BT HFP spec */ AT_SKIP_REST(buffer); AT_CHECK_RN(buffer); @@ -1374,6 +1378,11 @@ void bta_hf_client_at_parse(char *buf, unsigned int len) osi_free(tmp_buff); } + /* prevent buffer overflow in cases where LEN exceeds available buffer space */ + if (len > BTA_HF_CLIENT_AT_PARSER_MAX_LEN - bta_hf_client_cb.scb.at_cb.offset) { + return; + } + memcpy(bta_hf_client_cb.scb.at_cb.buf + bta_hf_client_cb.scb.at_cb.offset, buf, len); bta_hf_client_cb.scb.at_cb.offset += len; @@ -1571,7 +1580,7 @@ void bta_hf_client_send_at_xapl(char *information, UINT32 features) *vendorID: A string representation of the hex value of the vendor ID from the manufacturer, without the 0x prefix. *productID: A string representation of the hex value of the product ID from the manufacturer, without the 0x prefix. *version: The revision of the software. - *Fatures: A base-10 representation of a bit field. Available features are: + *Features: A base-10 representation of a bit field. Available features are: *Bit 0 = reserved *Bit 1 = The accessory supports battery reporting (reserved only for battery operated accessories). *Bit 2 = The accessory is docked or powered (reserved only for battery operated accessories). @@ -1827,7 +1836,7 @@ void bta_hf_client_send_at_bia(void) for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) { int sup = bta_hf_client_cb.scb.at_cb.indicator_lookup[i] == -1 ? 0 : 1; - at_len += snprintf(buf + at_len, BTA_HF_CLIENT_AT_MAX_LEN - at_len, "%u,", sup); + at_len += snprintf(buf + at_len, BTA_HF_CLIENT_AT_MAX_LEN - at_len, "%d,", sup); } buf[at_len - 1] = '\r'; diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c index 17eba5edd6..a49cfc91a0 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c @@ -2941,7 +2941,9 @@ void bta_jv_l2cap_connect_le(tBTA_JV_MSG *p_data) if (call_init_f) { cc->p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &evt, cc->user_data); } - t->init_called = TRUE; + if (t) { + t->init_called = TRUE; + } } diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_api.c b/components/bt/host/bluedroid/bta/jv/bta_jv_api.c index 7419501550..7fb74fdfa8 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_api.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_api.c @@ -696,7 +696,7 @@ on *******************************************************************************/ int BTA_JvL2capRead(UINT32 handle, UINT32 req_id, UINT8 *p_data, UINT16 len) { - tBTA_JV_L2CAP_READ evt_data; + tBTA_JV_L2CAP_READ evt_data = {0}; APPL_TRACE_API( "%s", __func__); diff --git a/components/bt/host/bluedroid/bta/sys/utl.c b/components/bt/host/bluedroid/bta/sys/utl.c index 94348e85f0..0c7954d45c 100644 --- a/components/bt/host/bluedroid/bta/sys/utl.c +++ b/components/bt/host/bluedroid/bta/sys/utl.c @@ -43,7 +43,7 @@ INT16 utl_str2int(const char *p_s) { INT32 val = 0; - for (; *p_s == ' ' && *p_s != 0; p_s++); + for (; *p_s == ' '; p_s++); if (*p_s == 0) { return -1; diff --git a/components/bt/host/bluedroid/btc/profile/esp/ble_button/button_pro.c b/components/bt/host/bluedroid/btc/profile/esp/ble_button/button_pro.c index 11126e0880..684c4e1da7 100644 --- a/components/bt/host/bluedroid/btc/profile/esp/ble_button/button_pro.c +++ b/components/bt/host/bluedroid/btc/profile/esp/ble_button/button_pro.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -115,7 +115,7 @@ static void button_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data) //uuid = {LEN_UUID_16, {ATT_CHAR_BUTTON_WIT}}; //start the button service after created esp_ble_gatts_start_srvc(p_data->create.service_id); - //add the frist button characteristic --> write characteristic + //add the first button characteristic --> write characteristic esp_ble_gatts_add_char(button_cb_env.clcb.cur_srvc_id, &uuid, (GATT_PERM_WRITE | GATT_PERM_READ), (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE)); @@ -128,15 +128,15 @@ static void button_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data) tBTA_GATT_CHAR_PROP prop = (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY); //save the att handle to the env button_cb_env.button_inst.but_wirt_hdl = p_data->add_result.attr_id; - //add the frist button characteristic --> Notify characteristic + //add the first button characteristic --> Notify characteristic esp_ble_gatts_add_char(button_cb_env.clcb.cur_srvc_id, &uuid, GATT_PERM_READ, (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY)); - } else if (p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_BUTTON_NTF) { // add the gattc config descriptor to the notify charateristic + } else if (p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_BUTTON_NTF) { // add the gattc config descriptor to the notify characteristic //tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_WRITE); uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG; button_cb_env.button_inst.but_ntf_hdl = p_data->add_result.attr_id; esp_ble_gatts_add_char_descr (button_cb_env.clcb.cur_srvc_id, - (GATT_PERM_WRITE | GATT_PERM_WRITE), + GATT_PERM_WRITE, &uuid); } @@ -151,7 +151,7 @@ static void button_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data) //BTA_GATTS_Listen(button_cb_env.gatt_if, true, NULL); break; case ESP_GATTS_CONNECT_EVT: - BTC_TRACE_ERROR("############BUTTON CONNCET EVT################\n"); + BTC_TRACE_ERROR("############BUTTON CONNECT EVT################\n"); //esp_ble_stop_advertising(); //set the connection flag to true button_env_clcb_alloc(p_data->conn.conn_id, p_data->conn.remote_bda); @@ -232,7 +232,7 @@ but_clcb_t *button_env_clcb_alloc (uint16_t conn_id, BD_ADDR remote_bda) ** ** Function button_env_find_conn_id_by_bd_adddr ** -** Description The function searches all LCB with macthing bd address +** Description The function searches all LCB with matching bd address ** ** Returns total number of clcb found. ** @@ -280,7 +280,7 @@ BOOLEAN button_env_clcb_dealloc(uint16_t conn_id) ** ** Function button_init ** -** Description Initializa the GATT Service for button profiles. +** Description Initialize the GATT Service for button profiles. ** *******************************************************************************/ esp_gatt_status_t button_init (but_prf_cb_t call_back) @@ -323,7 +323,7 @@ void button_msg_notify(uint16_t len, uint8_t *button_msg) //notify rsp==false; indicate rsp==true. BOOLEAN rsp = false; if (!conn_status && button_cb_env.clcb.congest) { - BTC_TRACE_ERROR("the conneciton for button profile has been loss\n"); + BTC_TRACE_ERROR("the connection for button profile has been loss\n"); return; } diff --git a/components/bt/host/bluedroid/btc/profile/esp/wechat_AirSync/wx_airsync_prf.c b/components/bt/host/bluedroid/btc/profile/esp/wechat_AirSync/wx_airsync_prf.c index 9ba7ceed69..13b3998da3 100644 --- a/components/bt/host/bluedroid/btc/profile/esp/wechat_AirSync/wx_airsync_prf.c +++ b/components/bt/host/bluedroid/btc/profile/esp/wechat_AirSync/wx_airsync_prf.c @@ -1,6 +1,6 @@ #include "wx_airsync_prf.h" /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -91,7 +91,7 @@ static void airsync_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data) airsync_cb_env.is_primery = p_data->create.is_primary; //start the airsync service after created esp_ble_gatts_start_srvc(p_data->create.service_id); - //add the frist airsync characteristic --> write characteristic + //add the first airsync characteristic --> write characteristic esp_ble_gatts_add_char(airsync_cb_env.clcb.cur_srvc_id, &uuid, (GATT_PERM_WRITE | GATT_PERM_READ), (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE)); @@ -112,7 +112,7 @@ static void airsync_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data) uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG; airsync_cb_env.airsync_inst.airsync_ntf_hdl = p_data->add_result.attr_id; esp_ble_gatts_add_char_descr (airsync_cb_env.clcb.cur_srvc_id, - (GATT_PERM_WRITE | GATT_PERM_WRITE), + GATT_PERM_WRITE, &uuid); uuid.uu.uuid16 = ATT_CHAR_AIRSYNC_READ; @@ -207,7 +207,7 @@ tAirSync_CLCB *airsync_env_clcb_alloc (UINT16 conn_id, BD_ADDR remote_bda) ** ** Function airsync_env_find_conn_id_by_bd_adddr ** -** Description The function searches all LCB with macthing bd address +** Description The function searches all LCB with matching bd address ** ** Returns total number of clcb found. ** @@ -231,7 +231,7 @@ UINT16 airsync_env_find_conn_id_by_bd_adddr(BD_ADDR remote_bda) ** ** Function airsync_init ** -** Description Initializa the GATT Service for airsync profiles. +** Description Initialize the GATT Service for airsync profiles. ** *******************************************************************************/ tGATT_STATUS AirSync_Init(tAIRSYNC_CBACK *call_back) diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c index abaf2da106..f4cdc8163e 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c @@ -290,14 +290,14 @@ static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_d /* Allocate buffer to hold the pointers (deep copy). The pointers will point to the end of the tBTA_DM_SEARCH */ switch (event) { case BTA_DM_INQ_RES_EVT: { - if (p_data->inq_res.p_eir) { + if (p_data && p_data->inq_res.p_eir) { param_len += HCI_EXT_INQ_RESPONSE_LEN; } } break; case BTA_DM_DISC_RES_EVT: { - if (p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) { + if (p_data && p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) { param_len += p_data->disc_res.raw_data_size; } } @@ -305,7 +305,7 @@ static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_d } /* if remote name is available in EIR, set the flag so that stack doesn't trigger RNR */ - if (event == BTA_DM_INQ_RES_EVT) { + if (p_data && (event == BTA_DM_INQ_RES_EVT)) { p_data->inq_res.remt_name_not_required = check_eir_remote_name(p_data, NULL, NULL); } @@ -457,7 +457,7 @@ static void bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_S } /* Allocate buffer to hold the pointers (deep copy). The pointers will point to the end of the tBTA_DM_SEARCH */ if (event == BTA_DM_DISC_RES_EVT) { - if (p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) { + if (p_data && p_data->disc_res.raw_data_size && p_data->disc_res.p_raw_data) { param_len += p_data->disc_res.raw_data_size; } } @@ -549,7 +549,7 @@ static void bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH switch (event) { case BTA_DM_DISC_RES_EVT: { - if ((p_data->disc_res.result == BTA_SUCCESS) && (p_data->disc_res.num_uuids > 0)) { + if (p_data && (p_data->disc_res.result == BTA_SUCCESS) && (p_data->disc_res.num_uuids > 0)) { param_len += (p_data->disc_res.num_uuids * MAX_UUID_SIZE); } } break; diff --git a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c index 63477d6ce5..84641f31c8 100644 --- a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c +++ b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c @@ -719,7 +719,7 @@ static void btc_l2cap_write(uint32_t handle) } l2cap_slot_t *slot = NULL; slot = l2cap_find_slot_by_handle(handle); - if (!slot || (slot && !slot->connected)) { + if (!slot || !slot->connected) { if (!slot) { BTC_TRACE_ERROR("%s unable to find l2cap slot!", __func__); } else { @@ -749,7 +749,7 @@ static void btc_l2cap_disconnect(uint32_t handle) } l2cap_slot_t *slot = NULL; slot = l2cap_find_slot_by_handle(handle); - if (!slot || (slot && !slot->connected)) { + if (!slot || !slot->connected) { if (!slot) { BTC_TRACE_ERROR("%s unable to find L2CAP slot! disconnect fail!", __func__); } else { diff --git a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c index 8607e42191..31a71992dc 100644 --- a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c +++ b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c @@ -713,7 +713,7 @@ static void btc_spp_disconnect(btc_spp_args_t *arg) spp_slot_t *slot = NULL; osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); slot = spp_find_slot_by_handle(arg->disconnect.handle); - if (!slot || (slot && !slot->connected)) { + if (!slot || !slot->connected) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); if (!slot) { BTC_TRACE_ERROR("%s unable to find RFCOMM slot! disconnect fail!", __func__); @@ -894,7 +894,7 @@ static void btc_spp_write(btc_spp_args_t *arg) spp_slot_t *slot = NULL; osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); slot = spp_find_slot_by_handle(arg->write.handle); - if (!slot || (slot && !slot->connected)) { + if (!slot || !slot->connected) { osi_mutex_unlock(&spp_local_param.spp_slot_mutex); if (!slot) { BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); diff --git a/components/bt/host/bluedroid/external/sbc/decoder/srce/decoder-sbc.c b/components/bt/host/bluedroid/external/sbc/decoder/srce/decoder-sbc.c index 553b4eddd4..cb5ed04947 100644 --- a/components/bt/host/bluedroid/external/sbc/decoder/srce/decoder-sbc.c +++ b/components/bt/host/bluedroid/external/sbc/decoder/srce/decoder-sbc.c @@ -305,7 +305,6 @@ OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, return OI_CODEC_SBC_CHECKSUM_MISMATCH; } -#ifdef OI_DEBUG /* * Make sure the bitpool values are sane. */ @@ -317,7 +316,6 @@ OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, ERROR(("Bitpool too large: %d (must be <= %ld)", context->common.frameInfo.bitpool, OI_SBC_MaxBitpool(&context->common.frameInfo))); return OI_STATUS_INVALID_PARAMETERS; } -#endif /* * Now decode the SBC data. Partial decode is not yet implemented for an SBC diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index e7cf219173..9eea4f988c 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -325,7 +325,7 @@ int hci_adv_credits_prep_to_release(uint16_t num) hci_hal_env.adv_credits_to_release = credits_to_release; osi_mutex_unlock(&hci_hal_env.adv_flow_lock); - if (credits_to_release == num && num != 0) { + if (credits_to_release == num) { osi_alarm_cancel(hci_hal_env.adv_flow_monitor); osi_alarm_set(hci_hal_env.adv_flow_monitor, HCI_ADV_FLOW_MONITOR_PERIOD_MS); } diff --git a/components/bt/host/bluedroid/stack/avct/avct_lcb_act.c b/components/bt/host/bluedroid/stack/avct/avct_lcb_act.c index b83219dceb..98dbaed809 100644 --- a/components/bt/host/bluedroid/stack/avct/avct_lcb_act.c +++ b/components/bt/host/bluedroid/stack/avct/avct_lcb_act.c @@ -86,6 +86,11 @@ static BT_HDR *avct_lcb_msg_asmbl(tAVCT_LCB *p_lcb, BT_HDR *p_buf) AVCT_TRACE_WARNING("Got start during reassembly"); } osi_free(p_lcb->p_rx_msg); + p_lcb->p_rx_msg = NULL; + if (sizeof(BT_HDR) + p_buf->offset + p_buf->len > BT_DEFAULT_BUFFER_SIZE) { + osi_free(p_buf); + return NULL; + } /* Allocate bigger buffer for reassembly. As lower layers are * not aware of possible packet size after reassembly they * would have allocated smaller buffer. diff --git a/components/bt/host/bluedroid/stack/avdt/avdt_msg.c b/components/bt/host/bluedroid/stack/avdt/avdt_msg.c index a049eee925..74b7b79184 100644 --- a/components/bt/host/bluedroid/stack/avdt/avdt_msg.c +++ b/components/bt/host/bluedroid/stack/avdt/avdt_msg.c @@ -1279,7 +1279,7 @@ BT_HDR *avdt_msg_asmbl(tAVDT_CCB *p_ccb, BT_HDR *p_buf) UINT8 *p; UINT8 pkt_type; BT_HDR *p_ret; - UINT16 buf_len; + size_t buf_len; /* parse the message header */ p = (UINT8 *)(p_buf + 1) + p_buf->offset; @@ -1314,6 +1314,10 @@ BT_HDR *avdt_msg_asmbl(tAVDT_CCB *p_ccb, BT_HDR *p_buf) * not aware of possible packet size after reassembly, they * would have allocated smaller buffer. */ + if (sizeof(BT_HDR) + p_buf->offset + p_buf->len > BT_DEFAULT_BUFFER_SIZE) { + osi_free(p_buf); + return NULL; + } p_ccb->p_rx_msg = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE); memcpy(p_ccb->p_rx_msg, p_buf, sizeof(BT_HDR) + p_buf->offset + p_buf->len); @@ -1351,7 +1355,7 @@ BT_HDR *avdt_msg_asmbl(tAVDT_CCB *p_ccb, BT_HDR *p_buf) p_buf->len -= AVDT_LEN_TYPE_CONT; /* verify length */ - if ((p_ccb->p_rx_msg->offset + p_buf->len) > buf_len) { + if (((size_t)p_ccb->p_rx_msg->offset + (size_t)p_buf->len) > buf_len) { /* won't fit; free everything */ AVDT_TRACE_WARNING("%s: Fragmented message too big!", __func__); osi_free(p_ccb->p_rx_msg); diff --git a/components/bt/host/bluedroid/stack/avdt/avdt_scb.c b/components/bt/host/bluedroid/stack/avdt/avdt_scb.c index 43bc4452c9..ca1e9f4c0f 100644 --- a/components/bt/host/bluedroid/stack/avdt/avdt_scb.c +++ b/components/bt/host/bluedroid/stack/avdt/avdt_scb.c @@ -749,14 +749,14 @@ UINT8 avdt_scb_verify(tAVDT_CCB *p_ccb, UINT8 state, UINT8 *p_seid, UINT16 num_s switch (state) { case AVDT_VERIFY_OPEN: case AVDT_VERIFY_START: - if (p_scb->state != AVDT_SCB_OPEN_ST && p_scb->state != AVDT_SCB_STREAM_ST) { + if (p_scb && p_scb->state != AVDT_SCB_OPEN_ST && p_scb->state != AVDT_SCB_STREAM_ST) { *p_err_code = AVDT_ERR_BAD_STATE; } break; case AVDT_VERIFY_SUSPEND: case AVDT_VERIFY_STREAMING: - if (p_scb->state != AVDT_SCB_STREAM_ST) { + if (p_scb && p_scb->state != AVDT_SCB_STREAM_ST) { *p_err_code = AVDT_ERR_BAD_STATE; } break; diff --git a/components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c b/components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c index c87e044fbc..5fae98eed8 100644 --- a/components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c +++ b/components/bt/host/bluedroid/stack/avdt/avdt_scb_act.c @@ -252,10 +252,16 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) UINT16 offset; UINT16 ex_len; UINT8 pad_len = 0; + uint16_t len = p_data->p_pkt->len; p = p_start = (UINT8 *)(p_data->p_pkt + 1) + p_data->p_pkt->offset; /* parse media packet header */ + offset = 12; // AVDT_MSG_PRS_OCTET1(1) + AVDT_MSG_PRS_M_PT(1) + UINT16(2) + UINT32(4) + 4 + if (len < offset) { + AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, offset); + goto length_error; + } AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc); AVDT_MSG_PRS_M_PT(p, m_pt, marker); BE_STREAM_TO_UINT16(seq, p); @@ -265,10 +271,16 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) UNUSED(o_v); /* skip over any csrc's in packet */ + offset += o_cc * 4; p += o_cc * 4; /* check for and skip over extension header */ if (o_x) { + offset += 4; + if (len < offset) { + AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, offset); + goto length_error; + } p += 2; BE_STREAM_TO_UINT16(ex_len, p); p += ex_len * 4; @@ -276,18 +288,20 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) /* save our new offset */ offset = (UINT16) (p - p_start); + if (len <= offset) { + goto length_error; + } /* 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(p_data->p_pkt); - p_data->p_pkt = NULL; + goto length_error; } /* adjust offset and length and send it up */ else { @@ -303,18 +317,22 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) #if AVDT_MULTIPLEXING == TRUE if ((p_scb->cs.p_media_cback != NULL) && (p_scb->p_media_buf != NULL) - && (p_scb->media_buf_len > p_data->p_pkt->len)) { + && (p_scb->media_buf_len > len)) { /* media buffer enough length is assigned by application. Lets use it*/ memcpy(p_scb->p_media_buf, (UINT8 *)(p_data->p_pkt + 1) + p_data->p_pkt->offset, - p_data->p_pkt->len); + len); (*p_scb->cs.p_media_cback)(avdt_scb_to_hdl(p_scb), p_scb->p_media_buf, p_scb->media_buf_len, time_stamp, seq, m_pt, marker); } #endif - osi_free(p_data->p_pkt); - p_data->p_pkt = NULL; + goto length_error; } } + return; + +length_error: + osi_free(p_data->p_pkt); + p_data->p_pkt = NULL; } #if AVDT_REPORTING == TRUE @@ -333,13 +351,18 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) UINT8 *p_start = p; UINT32 ssrc; UINT8 o_v, o_p, o_cc; + UINT32 min_len = 0; AVDT_REPORT_TYPE pt; - tAVDT_REPORT_DATA report, *p_rpt; + tAVDT_REPORT_DATA report; AVDT_TRACE_DEBUG( "avdt_scb_hdl_report"); if (p_scb->cs.p_report_cback) { - p_rpt = &report; /* parse report packet header */ + min_len += 8; + if (len < min_len) { + AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len); + goto avdt_scb_hdl_report_exit; + } AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc); pt = *p++; p += 2; @@ -352,6 +375,11 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) switch (pt) { case AVDT_RTCP_PT_SR: /* the packet type - SR (Sender Report) */ + min_len += 20; + if (len < min_len) { + AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len); + goto avdt_scb_hdl_report_exit; + } BE_STREAM_TO_UINT32(report.sr.ntp_sec, p); BE_STREAM_TO_UINT32(report.sr.ntp_frac, p); BE_STREAM_TO_UINT32(report.sr.rtp_time, p); @@ -360,6 +388,11 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) break; case AVDT_RTCP_PT_RR: /* the packet type - RR (Receiver Report) */ + min_len += 20; + if (len < min_len) { + AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len); + goto avdt_scb_hdl_report_exit; + } report.rr.frag_lost = *p; BE_STREAM_TO_UINT32(report.rr.packet_lost, p); report.rr.packet_lost &= 0xFFFFFF; @@ -370,11 +403,32 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) break; case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */ - if (*p == AVDT_RTCP_SDES_CNAME) { - p_rpt = (tAVDT_REPORT_DATA *)(p + 2); + min_len += 1; + if (len < min_len) { + AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len); + goto avdt_scb_hdl_report_exit; + } + uint8_t sdes_type; + BE_STREAM_TO_UINT8(sdes_type, p); + if (sdes_type == AVDT_RTCP_SDES_CNAME) { + min_len += 1; + if (len < min_len) { + AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len); + goto avdt_scb_hdl_report_exit; + } + uint8_t name_length; + BE_STREAM_TO_UINT8(name_length, p);\ + if ((name_length > len - min_len) || (name_length > AVDT_MAX_CNAME_SIZE)) { + result = AVDT_BAD_PARAMS; + } else { + BE_STREAM_TO_ARRAY(p, &(report.cname[0]), name_length); + } } else { - AVDT_TRACE_WARNING( " - SDES SSRC=0x%08x sc=%d %d len=%d %s\n", - ssrc, o_cc, *p, *(p + 1), p + 2); + if (len < min_len + 1) { + AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len); + goto avdt_scb_hdl_report_exit; + } + AVDT_TRACE_WARNING( " - SDES SSRC=0x%08x sc=%d %d len=%d\n", ssrc, o_cc, sdes_type, *p); result = AVDT_BUSY; } break; @@ -385,10 +439,12 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len) } if (result == AVDT_SUCCESS) { - (*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, p_rpt); + (*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, &report); } } + +avdt_scb_hdl_report_exit: p_start += len; return p_start; } @@ -624,7 +680,7 @@ void avdt_scb_hdl_pkt(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data) #endif #if AVDT_MULTIPLEXING == TRUE - /* select right function in dependance of is fragmentation supported or not */ + /* select right function in dependence of is fragmentation supported or not */ if ( 0 != (p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX)) { avdt_scb_hdl_pkt_frag(p_scb, p_data); } else diff --git a/components/bt/host/bluedroid/stack/avrc/avrc_api.c b/components/bt/host/bluedroid/stack/avrc/avrc_api.c index f7e31022d0..8f9646408f 100644 --- a/components/bt/host/bluedroid/stack/avrc/avrc_api.c +++ b/components/bt/host/bluedroid/stack/avrc/avrc_api.c @@ -200,7 +200,7 @@ static void avrc_send_continue_frag(UINT8 handle, UINT8 label) if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) { int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset); p_pkt_old = p_fcb->p_fmsg; - p_pkt = (BT_HDR *)osi_malloc((UINT16)(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE)); + p_pkt = (BT_HDR *)osi_calloc((UINT16)(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE)); if (p_pkt) { p_pkt->len = AVRC_MAX_CTRL_DATA_LEN; p_pkt->offset = AVCT_MSG_OFFSET; @@ -526,7 +526,7 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr, tAVRC_MSG_VENDOR *p_msg = &msg.vendor; if (cr == AVCT_CMD && - (p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < sizeof(p_pkt->len))) { + (p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < p_pkt->len)) { /* Ignore the invalid AV/C command frame */ #if (BT_USE_TRACES == TRUE) p_drop_msg = "dropped - too long AV/C cmd frame size"; diff --git a/components/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c b/components/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c index f185e7b569..43e1f8b471 100644 --- a/components/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c +++ b/components/bt/host/bluedroid/stack/avrc/avrc_pars_ct.c @@ -55,13 +55,27 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p if (p_msg->p_vendor_data == NULL) { return AVRC_STS_INTERNAL_ERR; } + if (p_msg->vendor_len < 4) { + AVRC_TRACE_WARNING("message length %u too short: must be at least 4", p_msg->vendor_len); + return AVRC_STS_INTERNAL_ERR; + } p = p_msg->p_vendor_data; BE_STREAM_TO_UINT8 (p_result->pdu, p); p++; /* skip the reserved/packe_type byte */ BE_STREAM_TO_UINT16 (len, p); AVRC_TRACE_DEBUG("avrc_pars_vendor_rsp() ctype:0x%x pdu:0x%x, len:%d/0x%x", p_msg->hdr.ctype, p_result->pdu, len, len); + + if (p_msg->vendor_len < len + 4) { + AVRC_TRACE_WARNING("message length %u too short: must be at least %u", p_msg->vendor_len, len + 4); + return AVRC_STS_INTERNAL_ERR; + } + if (p_msg->hdr.ctype == AVRC_RSP_REJ) { + if (len < 1) { + AVRC_TRACE_WARNING("invalid message length %u: must be at least 1", len); + return AVRC_STS_INTERNAL_ERR; + } p_result->rsp.status = *p; return p_result->rsp.status; } @@ -82,10 +96,18 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */ #if (AVRC_ADV_CTRL_INCLUDED == TRUE) + if (len < 1) { + AVRC_TRACE_WARNING("invalid message length %u: must be at least 1", len); + return AVRC_STS_INTERNAL_ERR; + } BE_STREAM_TO_UINT8 (eventid, p); if (AVRC_EVT_VOLUME_CHANGE == eventid && (AVRC_RSP_CHANGED == p_msg->hdr.ctype || AVRC_RSP_INTERIM == p_msg->hdr.ctype || AVRC_RSP_REJ == p_msg->hdr.ctype || AVRC_RSP_NOT_IMPL == p_msg->hdr.ctype)) { + if (len < 2) { + AVRC_TRACE_WARNING("invalid message length %u: must be at least 2", len); + return AVRC_STS_INTERNAL_ERR; + } p_result->reg_notif.status = p_msg->hdr.ctype; p_result->reg_notif.event_id = eventid; BE_STREAM_TO_UINT8 (p_result->reg_notif.param.volume, p); @@ -95,18 +117,30 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p break; #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */ case AVRC_PDU_GET_CAPABILITIES: /* 0x10 */ + if (len < 2) { + AVRC_TRACE_WARNING("invalid message length %u: must be at least 2", len); + return AVRC_STS_INTERNAL_ERR; + } BE_STREAM_TO_UINT8 (p_result->get_caps.capability_id, p); BE_STREAM_TO_UINT8 (p_result->get_caps.count, p); if (p_result->get_caps.capability_id == AVRC_CAP_EVENTS_SUPPORTED) { if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_EVT_ID) { status = AVRC_STS_INTERNAL_ERR; } else { + if (len < 2 + p_result->get_caps.count) { + AVRC_TRACE_WARNING("invalid message length %u: must be at least %d", len, 2 + p_result->get_caps.count); + return AVRC_STS_INTERNAL_ERR; + } BE_STREAM_TO_ARRAY(p, p_result->get_caps.param.event_id, p_result->get_caps.count); } } else if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) { if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_COMP_ID) { status = AVRC_STS_INTERNAL_ERR; } else { + if (len < 2 + p_result->get_caps.count * 6) { + AVRC_TRACE_WARNING("invalid message length %u: must be at least %d", len, 2 + p_result->get_caps.count * 6); + return AVRC_STS_INTERNAL_ERR; + } for (int i = 0; i < p_result->get_caps.count; ++i) { BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[i], p); } diff --git a/components/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c b/components/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c index a5fed6b2b0..cae87a2a9e 100644 --- a/components/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c +++ b/components/bt/host/bluedroid/stack/avrc/avrc_pars_tg.c @@ -242,7 +242,11 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_ status = AVRC_STS_INTERNAL_ERR; } else { BE_STREAM_TO_UINT8 (p_result->reg_notif.event_id, p); - BE_STREAM_TO_UINT32 (p_result->reg_notif.param, p); + if (AVRC_IS_VALID_EVENT_ID(p_result->reg_notif.event_id)) { + BE_STREAM_TO_UINT32 (p_result->reg_notif.param, p); + } else { + status = AVRC_STS_BAD_PARAM; + } } break; diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 4578e09ce2..ac01a8f651 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -792,6 +792,11 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable) if (p == NULL) { return; } + /* if we are trying to drop encryption on an encrypted connection, drop the connection */ + if (!encr_enable && (p->encrypt_state == BTM_ACL_ENCRYPT_STATE_ENCRYPT_ON)) { + btm_sec_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY); + return; + } /* Process Role Switch if active */ if (p->switch_role_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF) { /* if encryption turn off failed we still will try to switch role */ @@ -2247,7 +2252,7 @@ void BTM_BleGetPeriodicAdvListSize(uint8_t *size) ** Returns void ** *******************************************************************************/ -void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) +void btm_read_tx_power_complete (UINT8 *p, UINT16 evt_len, BOOLEAN is_ble) { tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_tx_power_cmpl_cb; tBTM_TX_POWER_RESULTS results; @@ -2260,12 +2265,23 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) btm_cb.devcb.p_tx_power_cmpl_cb = NULL; if (p_cb) { + if (evt_len < 1) { + BTM_TRACE_ERROR("Bogus event packet, too short\n"); + results.status = BTM_ERR_PROCESSING; + goto err_out; + } + STREAM_TO_UINT8 (results.hci_status, p); if (results.hci_status == HCI_SUCCESS) { results.status = BTM_SUCCESS; if (!is_ble) { + if (evt_len < 1 + 3) { + BTM_TRACE_ERROR("Bogus event packet, too short\n"); + results.status = BTM_ERR_PROCESSING; + goto err_out; + } STREAM_TO_UINT16 (handle, p); STREAM_TO_UINT8 (results.tx_power, p); @@ -2277,6 +2293,11 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) } #if BLE_INCLUDED == TRUE else { + if (evt_len < 1 + 1) { + BTM_TRACE_ERROR("Bogus event packet, too short\n"); + results.status = BTM_ERR_PROCESSING; + goto err_out; + } STREAM_TO_UINT8 (results.tx_power, p); memcpy(results.rem_bda, btm_cb.devcb.read_tx_pwr_addr, BD_ADDR_LEN); } @@ -2287,6 +2308,7 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) results.status = BTM_ERR_PROCESSING; } +err_out: (*p_cb)(&results); } } @@ -2301,7 +2323,7 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) ** Returns void ** *******************************************************************************/ -void btm_read_rssi_complete (UINT8 *p) +void btm_read_rssi_complete (UINT8 *p, UINT16 evt_len) { tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_rssi_cmpl_cb; tBTM_RSSI_RESULTS results; @@ -2314,11 +2336,21 @@ void btm_read_rssi_complete (UINT8 *p) btm_cb.devcb.p_rssi_cmpl_cb = NULL; if (p_cb) { + if (evt_len < 1) { + BTM_TRACE_ERROR("Bogus event packet, too short"); + results.status = BTM_ERR_PROCESSING; + goto err_out; + } STREAM_TO_UINT8 (results.hci_status, p); if (results.hci_status == HCI_SUCCESS) { results.status = BTM_SUCCESS; + if (evt_len < 1 + 3) { + BTM_TRACE_ERROR("Bogus event packet, too short"); + results.status = BTM_ERR_PROCESSING; + goto err_out; + } STREAM_TO_UINT16 (handle, p); STREAM_TO_UINT8 (results.rssi, p); @@ -2334,6 +2366,7 @@ void btm_read_rssi_complete (UINT8 *p) results.status = BTM_ERR_PROCESSING; } +err_out: (*p_cb)(&results); } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 236ae9226d..96bb69b0a9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -2384,7 +2384,7 @@ BOOLEAN BTM_BleVerifySignature (BD_ADDR bd_addr, UINT8 *p_orig, UINT16 len, UINT tBTM_SEC_DEV_REC *p_rec = btm_find_dev (bd_addr); UINT8 p_mac[BTM_CMAC_TLEN_SIZE]; - if (p_rec == NULL || (p_rec && !(p_rec->ble.key_type & BTM_LE_KEY_PCSRK))) { + if (p_rec == NULL || !(p_rec->ble.key_type & BTM_LE_KEY_PCSRK)) { BTM_TRACE_ERROR("can not verify signature for unknown device"); } else if (counter < p_rec->ble.keys.counter) { BTM_TRACE_ERROR("signature received with out dated sign counter"); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c b/components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c index c0ae0aaa2e..31c169a0c9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_adv_filter.c @@ -428,8 +428,7 @@ BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filte for (i = 0; i < cmn_ble_adv_vsc_cb.max_filter; i ++, p_addr_filter ++) { if ((p_addr_filter->in_use) && (NULL == p_bd_addr || - (NULL != p_bd_addr && - memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) { + (memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) { found = TRUE; memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT)); @@ -914,7 +913,7 @@ tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action, if (NULL == p_bda_filter || /* not a generic filter */ - (p_target != NULL && p_bda_filter)) { + (p_target != NULL)) { BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!"); return st; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index bfbf55ba76..5f9966c9f0 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -3757,7 +3757,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt 3. For same address and scan response, do nothing */ int same_addr = memcmp(bda, p_le_inq_cb->adv_addr, BD_ADDR_LEN); - if (same_addr != 0 || (same_addr == 0 && evt_type != BTM_BLE_SCAN_RSP_EVT)) { + if (same_addr != 0 || (evt_type != BTM_BLE_SCAN_RSP_EVT)) { btm_ble_process_last_adv_pkt(); } @@ -3808,8 +3808,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt /* new device */ if (p_i == NULL || /* assume a DUMO device, BR/EDR inquiry is always active */ - (p_i && - (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE && + ((p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE && p_i->scan_rsp)) { BTM_TRACE_WARNING("INQ RES: Extra Response Received...cancelling inquiry.."); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index 267ee83175..032c97fa33 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -227,6 +227,7 @@ void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add) void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len) { UINT8 status = 0; + STREAM_TO_UINT8(status, p); BTM_TRACE_DEBUG("%s status=%d", __func__, status); diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index e7bfc0740a..aa246e563f 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -1006,7 +1006,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb) ** Returns void ** *******************************************************************************/ -void btm_delete_stored_link_key_complete (UINT8 *p) +void btm_delete_stored_link_key_complete (UINT8 *p, UINT16 evt_len) { tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_stored_link_key_cmpl_cb; tBTM_DELETE_STORED_LINK_KEY_COMPLETE result; @@ -1018,10 +1018,16 @@ void btm_delete_stored_link_key_complete (UINT8 *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("Malformatted event packet, too short"); + result.status = BTM_ERR_PROCESSING; + goto err_out; + } /* Extract the result fields from the HCI event */ STREAM_TO_UINT8 (result.status, p); STREAM_TO_UINT16 (result.num_keys, p); +err_out: /* Call the call back and pass the result */ (*p_cb)(&result); } diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index 41a47300e7..c74f2b4396 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -1860,7 +1860,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode) /* new device response */ && ( p_i == NULL || /* existing device with BR/EDR info */ - (p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0) + ((p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0) ) #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_pm.c b/components/bt/host/bluedroid/stack/btm/btm_pm.c index 1c46a7446f..de48a2dad6 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_pm.c +++ b/components/bt/host/bluedroid/stack/btm/btm_pm.c @@ -866,9 +866,7 @@ void btm_pm_proc_ssr_evt (UINT8 *p, UINT16 evt_len) /* notify registered parties */ for (xx = 0; xx < BTM_MAX_PM_RECORDS; xx++) { if (btm_cb.pm_reg_db[xx].mask & BTM_PM_REG_NOTIF) { - if ( p_acl) { - (*btm_cb.pm_reg_db[xx].cback)( p_acl->remote_addr, BTM_PM_STS_SSR, use_ssr, status); - } + (*btm_cb.pm_reg_db[xx].cback)( p_acl->remote_addr, BTM_PM_STS_SSR, use_ssr, status); } } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_sec.c b/components/bt/host/bluedroid/stack/btm/btm_sec.c index db437e6f8c..5b281ccd87 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sec.c @@ -2748,11 +2748,16 @@ static void btm_sec_bond_cancel_complete (void) ** Returns void ** *******************************************************************************/ -void btm_create_conn_cancel_complete (UINT8 *p) +void btm_create_conn_cancel_complete (UINT8 *p, UINT16 evt_len) { UINT8 status; - STREAM_TO_UINT8 (status, p); + if (evt_len >= 1) { + STREAM_TO_UINT8 (status, p); + } else { + BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__); + status = BTM_ERR_PROCESSING; + } //BTM_TRACE_EVENT ("btm_create_conn_cancel_complete(): in State: %s status:%d\n", // btm_pair_state_descr(btm_cb.pairing_state), status); @@ -3795,13 +3800,27 @@ void btm_rem_oob_req (UINT8 *p) ** Returns void ** *******************************************************************************/ -void btm_read_local_oob_complete (UINT8 *p) +void btm_read_local_oob_complete (UINT8 *p, UINT16 evt_len) { tBTM_SP_LOC_OOB evt_data; - UINT8 status = *p++; + UINT8 status; + + if (evt_len < 1) { + BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__); + evt_data.status = BTM_ERR_PROCESSING; + goto err_out; + } + + STREAM_TO_UINT8(status, p); BTM_TRACE_EVENT ("btm_read_local_oob_complete:%d\n", status); if (status == HCI_SUCCESS) { + if (evt_len < 1 + 32) { + BTM_TRACE_ERROR("%s malformatted event packet, too short", __func__); + evt_data.status = BTM_ERR_PROCESSING; + goto err_out; + } + evt_data.status = BTM_SUCCESS; STREAM_TO_ARRAY16(evt_data.c, p); STREAM_TO_ARRAY16(evt_data.r, p); @@ -3809,6 +3828,7 @@ void btm_read_local_oob_complete (UINT8 *p) evt_data.status = BTM_ERR_PROCESSING; } +err_out: if (btm_cb.api.p_sp_callback) { (*btm_cb.api.p_sp_callback) (BTM_SP_LOC_OOB_EVT, (tBTM_SP_EVT_DATA *)&evt_data); } @@ -4267,7 +4287,6 @@ static void btm_sec_connect_after_reject_timeout (TIMER_LIST_ENT *p_tle) #if (SMP_INCLUDED == TRUE) void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) { - tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda); UINT8 res; UINT8 sec_dev_rec_status; BOOLEAN is_pairing_device = FALSE; @@ -4276,6 +4295,8 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) btm_acl_resubmit_page(); + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda); + /* Commenting out trace due to obf/compilation problems. */ #if (BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE) @@ -4598,7 +4619,6 @@ tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason) *******************************************************************************/ void btm_sec_disconnected (UINT16 handle, UINT8 reason) { - tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle); UINT8 old_pairing_flags = btm_cb.pairing_flags; int result = HCI_ERR_AUTH_FAILURE; tBTM_SEC_CALLBACK *p_callback = NULL; @@ -4611,6 +4631,8 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason) btm_acl_resubmit_page(); #endif + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle); + if (!p_dev_rec) { return; } @@ -5032,6 +5054,12 @@ void btm_sec_pin_code_request (UINT8 *p_bda) btm_pair_state_descr(btm_cb.pairing_state), (p_bda[0] << 8) + p_bda[1], (p_bda[2] << 24) + (p_bda[3] << 16) + (p_bda[4] << 8) + p_bda[5] ); #endif ///BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE + const bt_bdaddr_t *local_bd_addr = controller_get_interface()->get_address(); + if (!memcmp(p_bda, local_bd_addr, BD_ADDR_LEN)) { + BTM_TRACE_WARNING("btm_sec_pin_code_request() rejected device with same address\n"); + btsnd_hcic_pin_code_neg_reply(p_bda); + return; + } if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) { if ( (memcmp (p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) == 0) && (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_AUTH_COMPLETE) ) { diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index ed89f78ed4..b20e1fca43 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -1051,8 +1051,8 @@ void btm_cont_rswitch (tACL_CONN *p, tACL_CONN *btm_handle_to_acl (UINT16 hci_handle); void btm_read_link_policy_complete (UINT8 *p); -void btm_read_rssi_complete (UINT8 *p); -void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble); +void btm_read_rssi_complete (UINT8 *p, UINT16 evt_len); +void btm_read_tx_power_complete (UINT8 *p, UINT16 evt_len, BOOLEAN is_ble); void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types); void btm_read_link_quality_complete (UINT8 *p); tBTM_STATUS btm_set_packet_types (tACL_CONN *p, UINT16 pkt_types); @@ -1147,7 +1147,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 cc_opcode, UINT16 evt_len, void btm_inq_db_reset (void); void btm_vendor_specific_evt (UINT8 *p, UINT8 evt_len); #if (CLASSIC_BT_INCLUDED == TRUE) -void btm_delete_stored_link_key_complete (UINT8 *p); +void btm_delete_stored_link_key_complete (UINT8 *p, UINT16 evt_len); #endif // (CLASSIC_BT_INCLUDED == TRUE) void btm_report_device_status (tBTM_DEV_STATUS status); void btm_set_afh_channels_complete (UINT8 *p); @@ -1180,7 +1180,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_ UINT32 mx_proto_id, UINT32 mx_chan_id, tBTM_SEC_CALLBACK *p_callback, void *p_ref_data); void btm_sec_conn_req (UINT8 *bda, UINT8 *dc); -void btm_create_conn_cancel_complete (UINT8 *p); +void btm_create_conn_cancel_complete (UINT8 *p, UINT16 evt_len); void btm_read_linq_tx_power_complete (UINT8 *p); void btm_sec_init (UINT8 sec_mode); @@ -1222,10 +1222,10 @@ tINQ_DB_ENT *btm_inq_db_new (BD_ADDR p_bda); #if BTM_OOB_INCLUDED == TRUE void btm_rem_oob_req (UINT8 *p); -void btm_read_local_oob_complete (UINT8 *p); +void btm_read_local_oob_complete (UINT8 *p, UINT16 evt_len); #else #define btm_rem_oob_req(p) -#define btm_read_local_oob_complete(p) +#define btm_read_local_oob_complete(p, evt_len) #endif void btm_acl_resubmit_page (void); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index e94819486a..a66082b4d5 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -964,7 +964,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_DELETE_STORED_LINK_KEY: - btm_delete_stored_link_key_complete (p); + btm_delete_stored_link_key_complete (p, evt_len); break; #endif // (CLASSIC_BT_INCLUDED == TRUE) @@ -977,20 +977,20 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; case HCI_READ_RSSI: - btm_read_rssi_complete (p); + btm_read_rssi_complete (p, evt_len); 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: - btm_create_conn_cancel_complete(p); + btm_create_conn_cancel_complete(p, evt_len); break; case HCI_READ_LOCAL_OOB_DATA: #if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE - btm_read_local_oob_complete(p); + btm_read_local_oob_complete(p, evt_len); #endif break; @@ -1049,7 +1049,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l 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/components/bt/host/bluedroid/stack/gatt/att_protocol.c b/components/bt/host/bluedroid/stack/gatt/att_protocol.c index ef5deada20..c16967c6ef 100644 --- a/components/bt/host/bluedroid/stack/gatt/att_protocol.c +++ b/components/bt/host/bluedroid/stack/gatt/att_protocol.c @@ -200,7 +200,8 @@ BT_HDR *attp_build_read_by_type_value_cmd (UINT16 payload_size, tGATT_FIND_TYPE_ BT_HDR *attp_build_read_multi_cmd(UINT8 op_code, UINT16 payload_size, UINT16 num_handle, UINT16 *p_handle) { BT_HDR *p_buf = NULL; - UINT8 *p, i = 0; + UINT8 *p; + UINT16 i = 0; if ((p_buf = (BT_HDR *)osi_malloc((UINT16)(sizeof(BT_HDR) + num_handle * 2 + 1 + L2CAP_MIN_OFFSET))) != NULL) { p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET; diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_csm.c b/components/bt/host/bluedroid/stack/l2cap/l2c_csm.c index 9abe72e285..6236f12a94 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_csm.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_csm.c @@ -695,7 +695,7 @@ static void l2c_csm_config (tL2C_CCB *p_ccb, UINT16 event, void *p_data) l2cu_process_peer_cfg_rsp (p_ccb, p_cfg); if (p_cfg->result != L2CAP_CFG_PENDING) { - /* TBD: When config options grow beyong minimum MTU (48 bytes) + /* TBD: When config options grow beyond minimum MTU (48 bytes) * logic needs to be added to handle responses with * continuation bit set in flags field. * 1. Send additional config request out until C-bit is cleared in response @@ -885,7 +885,7 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data) tL2CAP_CFG_INFO *p_cfg; tL2C_CHNL_STATE tempstate; UINT8 tempcfgdone; - UINT8 cfg_result; + UINT8 cfg_result = L2CAP_PEER_CFG_DISCONNECT; #if (BT_TRACE_VERBOSE == TRUE) L2CAP_TRACE_EVENT ("L2CAP - LCID: 0x%04x st: OPEN evt: %s", @@ -916,7 +916,7 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data) case L2CEVT_LP_QOS_VIOLATION_IND: /* QOS violation */ /* Tell upper layer. If service guaranteed, then clear the channel */ - if (p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) { + if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) { (*p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb)(p_ccb->p_lcb->remote_bd_addr); } break; @@ -931,7 +931,11 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data) btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); - if ((cfg_result = l2cu_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_OK) { + if (p_cfg) { + cfg_result = l2cu_process_peer_cfg_req (p_ccb, p_cfg); + } + + if (cfg_result == L2CAP_PEER_CFG_OK) { (*p_ccb->p_rcb->api.pL2CA_ConfigInd_Cb)(p_ccb->local_cid, p_cfg); } @@ -968,7 +972,7 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data) break; case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - if ((p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_DataInd_Cb)) { + if (p_data && (p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_DataInd_Cb)) { (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR *)p_data); } break; @@ -988,16 +992,20 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data) break; case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ - l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_data); - l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); + if (p_data) { + l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_data); + l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); + } break; case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req */ - p_ccb->chnl_state = CST_CONFIG; - p_ccb->config_done &= ~CFG_DONE_MASK; - l2cu_process_our_cfg_req (p_ccb, (tL2CAP_CFG_INFO *)p_data); - l2cu_send_peer_config_req (p_ccb, (tL2CAP_CFG_INFO *)p_data); - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); + if (p_data) { + p_ccb->chnl_state = CST_CONFIG; + p_ccb->config_done &= ~CFG_DONE_MASK; + l2cu_process_our_cfg_req (p_ccb, (tL2CAP_CFG_INFO *)p_data); + l2cu_send_peer_config_req (p_ccb, (tL2CAP_CFG_INFO *)p_data); + btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); + } break; case L2CEVT_TIMEOUT: diff --git a/components/bt/host/bluedroid/stack/rfcomm/port_api.c b/components/bt/host/bluedroid/stack/rfcomm/port_api.c index 1aa38ff77c..a6b5920cdb 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/port_api.c +++ b/components/bt/host/bluedroid/stack/rfcomm/port_api.c @@ -181,7 +181,7 @@ int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server, /* If the MTU is not specified (0), keep MTU decision until the * PN frame has to be send * at that time connection should be established and we - * will know for sure our prefered MTU + * will know for sure our preferred MTU */ rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD; @@ -298,12 +298,12 @@ int RFCOMM_RemoveServer (UINT16 handle) ** ** Description This function is called to provide an address of the ** function which will be called when one of the events -** specified in the mask occures. +** specified in the mask occurs. ** ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection ** p_callback - address of the callback function which should ** be called from the RFCOMM when an event -** specified in the mask occures. +** specified in the mask occurs. ** ** *******************************************************************************/ @@ -537,8 +537,7 @@ BOOLEAN PORT_IsOpening (BD_ADDR bd_addr) } } - if ((!found_port) || - (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) { + if ((!found_port) || (p_port->rfc.state < RFC_STATE_OPENED)) { /* Port is not established yet. */ memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN); return TRUE; @@ -641,7 +640,7 @@ int PORT_GetRxQueueCnt (UINT16 handle, UINT16 *p_rx_queue_count) ** Function PORT_GetState ** ** Description This function is called to fill tPORT_STATE structure -** with the curremt control settings for the port +** with the current control settings for the port ** ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection ** p_settings - Pointer to a tPORT_STATE structure in which @@ -1009,15 +1008,15 @@ int PORT_GetModemStatus (UINT16 handle, UINT8 *p_signal) ** ** Function PORT_ClearError ** -** Description This function retreives information about a communications +** Description This function retrieves information about a communications ** error and reports current status of a connection. The -** function should be called when an error occures to clear +** function should be called when an error occurs to clear ** the connection error flag and to enable additional read ** and write operations. ** ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection ** p_errors - pointer of the variable to receive error codes -** p_status - pointer to the tPORT_STATUS structur to receive +** p_status - pointer to the tPORT_STATUS structure to receive ** connection status ** *******************************************************************************/ @@ -1090,7 +1089,7 @@ int PORT_SendError (UINT16 handle, UINT8 errors) ** Description This function reports current status of a connection. ** ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection -** p_status - pointer to the tPORT_STATUS structur to receive +** p_status - pointer to the tPORT_STATUS structure to receive ** connection status ** *******************************************************************************/ @@ -1700,7 +1699,7 @@ int PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len) rc = port_write (p_port, p_buf); - /* If queue went below the threashold need to send flow control */ + /* If queue went below the threshold need to send flow control */ event |= port_flow_control_user (p_port); if (rc == PORT_SUCCESS) { diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_db.c b/components/bt/host/bluedroid/stack/sdp/sdp_db.c index f9f2f738c6..06f934d4a3 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_db.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_db.c @@ -415,6 +415,10 @@ BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, UINT8 attr_type, tSDP_RECORD *p_rec = NULL; list_node_t *p_node= NULL; + if (!p_val) { + return FALSE; + } + #if (BT_TRACE_VERBOSE == TRUE) if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) { if ((attr_type == UINT_DESC_TYPE) || @@ -448,6 +452,12 @@ BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, UINT8 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 */ diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c b/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c index e1ffdf7261..82ef1548da 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c @@ -45,9 +45,9 @@ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /********************************************************************************/ #if SDP_CLIENT_ENABLED == TRUE -static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply); -static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply); -static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply); +static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end); +static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end); +static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end); static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end); static tSDP_DISC_REC *add_record (tSDP_DISCOVERY_DB *p_db, BD_ADDR p_bda); static UINT8 *add_attr (UINT8 *p, UINT8 *p_end, tSDP_DISCOVERY_DB *p_db, tSDP_DISC_REC *p_rec, @@ -189,7 +189,7 @@ void sdp_disc_connected (tCONN_CB *p_ccb) if (p_ccb->is_attr_search) { p_ccb->disc_state = SDP_DISC_WAIT_SEARCH_ATTR; - process_service_search_attr_rsp (p_ccb, NULL); + process_service_search_attr_rsp (p_ccb, NULL, NULL); } else { /* First step is to get a list of the handles from the server. */ /* We are not searching for a specific attribute, so we will */ @@ -213,7 +213,7 @@ void sdp_disc_connected (tCONN_CB *p_ccb) *******************************************************************************/ void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg) { - UINT8 *p, rsp_pdu; + UINT8 *p, *p_end, rsp_pdu; BOOLEAN invalid_pdu = TRUE; #if (SDP_DEBUG_RAW == TRUE) @@ -225,7 +225,12 @@ void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg) /* Got a reply!! Check what we got back */ p = (UINT8 *)(p_msg + 1) + p_msg->offset; + p_end = p + p_msg->len; + if (p_msg->len < 1) { + sdp_disconnect(p_ccb, SDP_GENERIC_ERROR); + return; + } BE_STREAM_TO_UINT8 (rsp_pdu, p); p_msg->len--; @@ -233,21 +238,21 @@ void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg) switch (rsp_pdu) { case SDP_PDU_SERVICE_SEARCH_RSP: if (p_ccb->disc_state == SDP_DISC_WAIT_HANDLES) { - process_service_search_rsp (p_ccb, p); + process_service_search_rsp (p_ccb, p, p_end); invalid_pdu = FALSE; } break; case SDP_PDU_SERVICE_ATTR_RSP: if (p_ccb->disc_state == SDP_DISC_WAIT_ATTR) { - process_service_attr_rsp (p_ccb, p); + process_service_attr_rsp (p_ccb, p, p_end); invalid_pdu = FALSE; } break; case SDP_PDU_SERVICE_SEARCH_ATTR_RSP: if (p_ccb->disc_state == SDP_DISC_WAIT_SEARCH_ATTR) { - process_service_search_attr_rsp (p_ccb, p); + process_service_search_attr_rsp (p_ccb, p, p_end); invalid_pdu = FALSE; } break; @@ -269,12 +274,17 @@ void sdp_disc_server_rsp (tCONN_CB *p_ccb, BT_HDR *p_msg) ** Returns void ** *******************************************************************************/ -static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) +static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end) { UINT16 xx; UINT16 total, cur_handles, orig; UINT8 cont_len; + if (p_reply + 8 > p_reply_end) { + sdp_disconnect (p_ccb, SDP_GENERIC_ERROR); + return; + } + /* Skip transaction, and param len */ p_reply += 4; BE_STREAM_TO_UINT16 (total, p_reply); @@ -282,7 +292,7 @@ static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) orig = p_ccb->num_handles; p_ccb->num_handles += cur_handles; - if (p_ccb->num_handles == 0) { + if ((p_ccb->num_handles == 0) || (p_ccb->num_handles < orig)) { SDP_TRACE_WARNING ("SDP - Rcvd ServiceSearchRsp, no matches\n"); sdp_disconnect (p_ccb, SDP_NO_RECS_MATCH); return; @@ -296,6 +306,11 @@ static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) p_ccb->num_handles = sdp_cb.max_recs_per_search; } + if (p_reply + ((p_ccb->num_handles - orig) * 4) + 1 > p_reply_end) { + sdp_disconnect(p_ccb, SDP_GENERIC_ERROR); + return; + } + for (xx = orig; xx < p_ccb->num_handles; xx++) { BE_STREAM_TO_UINT32 (p_ccb->handles[xx], p_reply); } @@ -306,6 +321,10 @@ static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) sdp_disconnect (p_ccb, SDP_INVALID_CONT_STATE); return; } + if (p_reply + cont_len > p_reply_end) { + sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE); + return; + } /* stay in the same state */ sdp_snd_service_search_req(p_ccb, cont_len, p_reply); } else { @@ -313,7 +332,7 @@ static void process_service_search_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) p_ccb->disc_state = SDP_DISC_WAIT_ATTR; /* Kick off the first attribute request */ - process_service_attr_rsp (p_ccb, NULL); + process_service_attr_rsp (p_ccb, NULL, NULL); } } @@ -392,7 +411,7 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset) ** Returns void ** *******************************************************************************/ -static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) +static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end) { UINT8 *p_start, *p_param_len; UINT16 param_len, list_byte_count; @@ -411,6 +430,11 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) /* Skip transaction ID and length */ p_reply += 4; + if (p_reply + 2 > p_reply_end) { + sdp_disconnect (p_ccb, SDP_INVALID_PDU_SIZE); + return; + } + BE_STREAM_TO_UINT16 (list_byte_count, p_reply); #if (SDP_DEBUG_RAW == TRUE) SDP_TRACE_WARNING("list_byte_count:%d\n", list_byte_count); @@ -426,6 +450,12 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) SDP_TRACE_WARNING("list_len: %d, list_byte_count: %d\n", p_ccb->list_len, list_byte_count); #endif + + if (p_reply + list_byte_count + 1 /* continuation */ > p_reply_end) { + sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE); + return; + } + if (p_ccb->rsp_list == NULL) { p_ccb->rsp_list = (UINT8 *)osi_malloc (SDP_MAX_LIST_BYTE_COUNT); if (p_ccb->rsp_list == NULL) { @@ -502,8 +532,10 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) /* Was this a continuation request ? */ if (cont_request_needed) { - memcpy (p, p_reply, *p_reply + 1); - p += *p_reply + 1; + if (p_reply + *p_reply + 1 <= p_reply_end) { + memcpy (p, p_reply, *p_reply + 1); + p += *p_reply + 1; + } } else { UINT8_TO_BE_STREAM (p, 0); } @@ -537,7 +569,7 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) ** Returns void ** *******************************************************************************/ -static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) +static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_reply_end) { UINT8 *p, *p_start, *p_end, *p_param_len; UINT8 type; @@ -557,6 +589,11 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) /* Skip transaction ID and length */ p_reply += 4; + if (p_reply + 2 > p_reply_end) { + sdp_disconnect (p_ccb, SDP_INVALID_PDU_SIZE); + return; + } + BE_STREAM_TO_UINT16 (lists_byte_count, p_reply); #if (SDP_DEBUG_RAW == TRUE) SDP_TRACE_WARNING("lists_byte_count:%d\n", lists_byte_count); @@ -572,6 +609,12 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) SDP_TRACE_WARNING("list_len: %d, list_byte_count: %d\n", p_ccb->list_len, lists_byte_count); #endif + + if (p_reply + lists_byte_count + 1 /* continuation */ > p_reply_end) { + sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE); + return; + } + if (p_ccb->rsp_list == NULL) { p_ccb->rsp_list = (UINT8 *)osi_malloc (SDP_MAX_LIST_BYTE_COUNT); if (p_ccb->rsp_list == NULL) { @@ -643,8 +686,10 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply) /* No continuation for first request */ if (p_reply) { - memcpy (p, p_reply, *p_reply + 1); - p += *p_reply + 1; + if (p_reply + *p_reply + 1 <= p_reply_end) { + memcpy (p, p_reply, *p_reply + 1); + p += *p_reply + 1; + } } else { UINT8_TO_BE_STREAM (p, 0); } diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_server.c b/components/bt/host/bluedroid/stack/sdp/sdp_server.c index d6f98197d0..43e3664baf 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_server.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_server.c @@ -179,7 +179,6 @@ static void process_service_search (tCONN_CB *p_ccb, UINT16 trans_num, tSDP_RECORD *p_rec = NULL; BT_HDR *p_buf; BOOLEAN is_cont = FALSE; - UNUSED(p_req_end); p_req = sdpu_extract_uid_seq (p_req, param_len, &uid_seq); @@ -214,6 +213,10 @@ static void process_service_search (tCONN_CB *p_ccb, UINT16 trans_num, } /* Check if this is a continuation request */ + if (p_req + 1 > p_req_end) { + sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN); + return; + } if (*p_req) { if (*p_req++ != SDP_CONTINUATION_LEN || (p_req >= p_req_end)) { sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, @@ -351,6 +354,10 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num, } /* Check if this is a continuation request */ + if (p_req + 1 > p_req_end) { + sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN); + return; + } if (*p_req) { /* Free and reallocate buffer */ if (p_ccb->rsp_list) { @@ -565,7 +572,7 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 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 + 2 > p_req_end)) { sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX, SDP_TEXT_BAD_UUID_LIST); return; } @@ -586,7 +593,16 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num, memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ)) ; + if (max_list_len < 4) { + sdpu_build_n_send_error (p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL); + return; + } + /* Check if this is a continuation request */ + if (p_req + 1 > p_req_end) { + sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN); + return; + } if (*p_req) { /* Free and reallocate buffer */ if (p_ccb->rsp_list) { @@ -600,7 +616,7 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num, return; } - if (*p_req++ != SDP_CONTINUATION_LEN) { + if ((*p_req++ != SDP_CONTINUATION_LEN) || (p_req + 2 > 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/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index 591c083c5d..d05e1a7f7d 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -865,7 +865,7 @@ void smp_br_process_pairing_command(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) SMP_TRACE_DEBUG("%s", __func__); /* rejecting BR pairing request over non-SC BR link */ - if (!p_dev_rec->new_encryption_key_is_p256 && p_cb->role == HCI_ROLE_SLAVE) { + if (p_dev_rec && !p_dev_rec->new_encryption_key_is_p256 && p_cb->role == HCI_ROLE_SLAVE) { reason = SMP_XTRANS_DERIVE_NOT_ALLOW; smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &reason); return; @@ -1343,7 +1343,14 @@ void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) /* state check to prevent re-entrant */ if (smp_get_state() == SMP_STATE_BOND_PENDING) { if (p_cb->derive_lk) { - smp_derive_link_key_from_long_term_key(p_cb, NULL); + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda); + if (!(p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED) && + (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED)) { + SMP_TRACE_DEBUG("%s BREDR key is higher security than existing LE keys, " + "don't derive LK from LTK", __func__); + } else { + smp_derive_link_key_from_long_term_key(p_cb, NULL); + } p_cb->derive_lk = FALSE; } diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index 855017a76a..3b1d4ee8f1 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -2231,7 +2231,7 @@ void smp_process_new_nonce(tSMP_CB *p_cb) static void smp_rand_back(tBTM_RAND_ENC *p) { tSMP_CB *p_cb = &smp_cb; - UINT8 *pp = p->param_buf; + UINT8 *pp = NULL; UINT8 failure = SMP_PAIR_FAIL_UNKNOWN; UINT8 state = p_cb->rand_enc_proc_state & ~0x80; @@ -2249,11 +2249,13 @@ static void smp_rand_back(tBTM_RAND_ENC *p) break; case SMP_GEN_DIV_LTK: + pp = p->param_buf; STREAM_TO_UINT16(p_cb->div, pp); smp_generate_ltk_cont(p_cb, NULL); break; case SMP_GEN_DIV_CSRK: + pp = p->param_buf; STREAM_TO_UINT16(p_cb->div, pp); smp_compute_csrk(p_cb, NULL); break; diff --git a/components/bt/host/bluedroid/stack/smp/smp_l2c.c b/components/bt/host/bluedroid/stack/smp/smp_l2c.c index 1f3db502e2..c109b9d002 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_l2c.c +++ b/components/bt/host/bluedroid/stack/smp/smp_l2c.c @@ -320,6 +320,12 @@ static void smp_br_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf) UINT8 cmd ; SMP_TRACE_EVENT ("SMDBG l2c %s\n", __func__); + if (p_buf->len < 1) { + SMP_TRACE_WARNING( "Bogus l2cap packet, too short"); + osi_free(p_buf); + return; + } + STREAM_TO_UINT8(cmd, p); /* sanity check */ @@ -331,6 +337,11 @@ static void smp_br_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf) /* reject the pairing request if there is an on-going SMP pairing */ if (SMP_OPCODE_PAIRING_REQ == cmd) { + if (p_buf->len != smp_cmd_size_per_spec[cmd]) { + SMP_TRACE_WARNING( "Ignore received command 0x%02x with invalid length %d", cmd, p_buf->len); + osi_free(p_buf); + return; + } if ((p_cb->state == SMP_STATE_IDLE) && (p_cb->br_state == SMP_BR_STATE_IDLE)) { p_cb->role = HCI_ROLE_SLAVE; p_cb->smp_over_br = TRUE;