diff --git a/components/bt/host/bluedroid/api/esp_ble_iso_api.c b/components/bt/host/bluedroid/api/esp_ble_iso_api.c index 826991e6bf..d2239844f0 100644 --- a/components/bt/host/bluedroid/api/esp_ble_iso_api.c +++ b/components/bt/host/bluedroid/api/esp_ble_iso_api.c @@ -37,6 +37,10 @@ esp_err_t esp_ble_iso_create_big(esp_ble_iso_big_creat_params_t *big_creat_param return ESP_ERR_INVALID_ARG; } + if (big_creat_param->num_bis > BLE_ISO_BIS_MAX_COUNT) { + return ESP_ERR_INVALID_ARG; + } + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_ISO_BLE; msg.act = BTC_ISO_ACT_BIG_CREATE; @@ -58,6 +62,10 @@ esp_err_t esp_ble_iso_create_big_test(esp_ble_iso_big_creat_test_params_t *big_c return ESP_ERR_INVALID_ARG; } + if (big_creat_test_param->num_bis > BLE_ISO_BIS_MAX_COUNT) { + return ESP_ERR_INVALID_ARG; + } + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_ISO_BLE; msg.act = BTC_ISO_ACT_BIG_CREATE_TEST; diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 906e1280ba..2e60cf4dd4 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -1940,6 +1940,10 @@ esp_err_t esp_ble_gap_set_path_loss_reporting_params(esp_ble_path_loss_rpt_param return ESP_ERR_INVALID_STATE; } + if (path_loss_rpt_params == NULL) { + return ESP_ERR_INVALID_ARG; + } + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_SET_PATH_LOSS_REPORT_PARAMS; @@ -2006,7 +2010,7 @@ esp_err_t esp_ble_gap_set_default_subrate(esp_ble_default_subrate_param_t *defau } if (!default_subrate_params) { - return ESP_ERR_NOT_ALLOWED; + return ESP_ERR_INVALID_ARG; } msg.sig = BTC_SIG_API_CALL; @@ -2033,7 +2037,7 @@ esp_err_t esp_ble_gap_subrate_request(esp_ble_subrate_req_param_t *subrate_req_p } if (!subrate_req_params) { - return ESP_ERR_NOT_ALLOWED; + return ESP_ERR_INVALID_ARG; } msg.sig = BTC_SIG_API_CALL; diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 2ff4cab670..2c6d32ac9a 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -2182,14 +2182,12 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) uint16_t params_len = src->per_adv_subevent_data_params.num_subevents_with_data * sizeof(esp_ble_subevent_params); dst->per_adv_subevent_data_params.subevent_params = osi_malloc(params_len); if (dst->per_adv_subevent_data_params.subevent_params) { - for (uint8_t i = 0; i < src->per_adv_subevent_data_params.num_subevents_with_data; i++) { - memcpy(&dst->per_adv_subevent_data_params.subevent_params[i], &src->per_adv_subevent_data_params.subevent_params[i], params_len); - // dst->per_adv_subevent_data_params.subevent_params[i].subevent = src->per_adv_subevent_data_params.subevent_params[i].subevent; - // dst->per_adv_subevent_data_params.subevent_params[i].response_slot_start = src->per_adv_subevent_data_params.subevent_params[i].response_slot_start; - // dst->per_adv_subevent_data_params.subevent_params[i].response_slot_count = src->per_adv_subevent_data_params.subevent_params[i].response_slot_count; - // dst->per_adv_subevent_data_params.subevent_params[i].subevent_data_len = src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len; + /* Fix: Use sizeof(esp_ble_subevent_params) instead of params_len to prevent buffer overflow */ + memcpy(&dst->per_adv_subevent_data_params.subevent_params[i], + &src->per_adv_subevent_data_params.subevent_params[i], + sizeof(esp_ble_subevent_params)); dst->per_adv_subevent_data_params.subevent_params[i].subevent_data = osi_malloc(src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len); if (dst->per_adv_subevent_data_params.subevent_params[i].subevent_data) { memcpy(dst->per_adv_subevent_data_params.subevent_params[i].subevent_data, src->per_adv_subevent_data_params.subevent_params[i].subevent_data, src->per_adv_subevent_data_params.subevent_params[i].subevent_data_len); @@ -2267,6 +2265,9 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) #if (BT_BLE_FEAT_PAWR_EN == TRUE) case ESP_GAP_BLE_PERIODIC_ADV_RESPONSE_REPORT_EVT: if (src->pa_rsp_rpt_evt.pa_rsp_info) { + // num_rsp is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate + dst->pa_rsp_rpt_evt.num_rsp = src->pa_rsp_rpt_evt.num_rsp; + dst->pa_rsp_rpt_evt.pa_rsp_info = osi_malloc(src->pa_rsp_rpt_evt.num_rsp * sizeof(esp_ble_pa_rsp_info)); if (dst->pa_rsp_rpt_evt.pa_rsp_info) { for (UINT8 i = 0; i < src->pa_rsp_rpt_evt.num_rsp; i++) @@ -2276,18 +2277,22 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) dst->pa_rsp_rpt_evt.pa_rsp_info[i].cte_type = src->pa_rsp_rpt_evt.pa_rsp_info[i].cte_type; dst->pa_rsp_rpt_evt.pa_rsp_info[i].rsp_slot = src->pa_rsp_rpt_evt.pa_rsp_info[i].rsp_slot; dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_status = src->pa_rsp_rpt_evt.pa_rsp_info[i].data_status; + // data_len is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_len = src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len; - if (src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len) { + if (src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len && src->pa_rsp_rpt_evt.pa_rsp_info[i].data) { dst->pa_rsp_rpt_evt.pa_rsp_info[i].data = osi_malloc(src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len); if (dst->pa_rsp_rpt_evt.pa_rsp_info[i].data) { memcpy(dst->pa_rsp_rpt_evt.pa_rsp_info[i].data, src->pa_rsp_rpt_evt.pa_rsp_info[i].data, src->pa_rsp_rpt_evt.pa_rsp_info[i].data_len); } else { - BTC_TRACE_ERROR("%s, data, no enough memory.", __func__); + BTC_TRACE_ERROR("%s, data, no enough memory for data_len %d at index %d", __func__, dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_len, i); + dst->pa_rsp_rpt_evt.pa_rsp_info[i].data_len = 0; } + } else { + dst->pa_rsp_rpt_evt.pa_rsp_info[i].data = NULL; } } } else { - BTC_TRACE_ERROR("%s, pa_rsp_info, no enough memory.", __func__); + BTC_TRACE_ERROR("%s, pa_rsp_info, no enough memory for array size %d", __func__, src->pa_rsp_rpt_evt.num_rsp); } } break; diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index 4823df6c5d..183e3fdde1 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -320,8 +320,8 @@ #define BLE_ISO_CIS_MAX_COUNT (0) #endif -#ifdef CONFIG_BT_BLE_ISO_BIS_MAX_COUNT -#define BLE_ISO_BIS_MAX_COUNT CONFIG_BT_BLE_ISO_BIS_MAX_COUNT +#ifdef UC_BT_BLE_ISO_BIS_MAX_COUNT +#define BLE_ISO_BIS_MAX_COUNT UC_BT_BLE_ISO_BIS_MAX_COUNT #else #define BLE_ISO_BIS_MAX_COUNT (0) #endif diff --git a/components/bt/host/bluedroid/hci/ble_hci_iso.c b/components/bt/host/bluedroid/hci/ble_hci_iso.c index 9c73fae237..6a61836ef2 100644 --- a/components/bt/host/bluedroid/hci/ble_hci_iso.c +++ b/components/bt/host/bluedroid/hci/ble_hci_iso.c @@ -64,16 +64,16 @@ ble_hci_set_iso_buf_sz(uint16_t pktlen, uint8_t max_pkts) ble_hs_iso_avail_pkts = max_pkts; #endif /* (BLE_ISO_STD_FLOW_CTRL) */ - HCI_TRACE_WARNING("ISO Flow Control:\n"); - HCI_TRACE_WARNING(" Length: %u\n", pktlen); - HCI_TRACE_WARNING(" Count: %u\n", max_pkts); - HCI_TRACE_WARNING(" Status: "); + HCI_TRACE_DEBUG("ISO Flow Control:"); + HCI_TRACE_DEBUG("Length: %u\n", pktlen); + HCI_TRACE_DEBUG("Count: %u\n", max_pkts); + HCI_TRACE_DEBUG("Status: "); #if (BLE_ISO_STD_FLOW_CTRL == TRUE) - HCI_TRACE_WARNING("%s\n", "Standard"); + HCI_TRACE_DEBUG("%s", "Standard"); #elif (BLE_ISO_NON_STD_FLOW_CTRL == TRUE) - HCI_TRACE_WARNING("%s\n", "Non-standard"); + HCI_TRACE_DEBUG("%s\n", "Non-standard"); #else - HCI_TRACE_WARNING("%s\n", "Not support"); + HCI_TRACE_DEBUG("%s\n", "Not support"); #endif return 0; @@ -261,7 +261,7 @@ ble_hci_iso_tx_now(struct ble_hci_iso_conn *conn, const uint8_t *sdu, #endif dlh_len = (conn->ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0) + BLE_HCI_ISO_DATA_LOAD_HDR_SZ; - + // free in controller frag = malloc(BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + conn->sdu_len); if (frag == NULL) { HCI_TRACE_ERROR("frag is null\n"); @@ -279,7 +279,7 @@ ble_hci_iso_tx_now(struct ble_hci_iso_conn *conn, const uint8_t *sdu, rc = ble_hci_tx_iso_data(frag, BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + conn->sdu_len, NULL); if (rc) { - HCI_TRACE_ERROR("iso tx failed\n"); + HCI_TRACE_ERROR("iso tx failed_%d\n", rc); return 14; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index b87c9d35f6..81eb92414b 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -17,6 +17,7 @@ tBTM_BLE_EXTENDED_CB extend_adv_cb; tBTM_BLE_5_HCI_CBACK ble_5_hci_cb; #define INVALID_VALUE 0XFF + extern BOOLEAN BTM_GetLocalResolvablePrivateAddr(BD_ADDR bda); extern void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda); extern void BTM_BleSetStaticAddr(BD_ADDR rand_addr); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c b/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c index a79932de2f..2e9c06da45 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_cte.c @@ -38,8 +38,6 @@ void BTM_CteBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_CTE_CB_PARAM #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) tBTM_STATUS BTM_BleSetCteTransParams(uint8_t adv_handle, uint8_t cte_len, uint8_t cte_type, uint8_t cte_count, uint8_t switching_pattern_len, uint8_t *antenna_ids) { - - tHCI_STATUS err = HCI_SUCCESS; tBTM_STATUS status = BTM_SUCCESS; tBTM_BLE_CTE_CB_PARAMS cb_params = {0}; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c b/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c index c66f10b9c0..f0aa7ca56c 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c @@ -85,11 +85,20 @@ void btm_ble_iso_read_iso_link_quality_complete(UINT8 *p) void btm_ble_iso_set_cig_params_complete(UINT8 *p) { tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + UINT8 cis_count; STREAM_TO_UINT8(cb_params.btm_set_cig_params.status, p); STREAM_TO_UINT8(cb_params.btm_set_cig_params.cig_id, p); - STREAM_TO_UINT8(cb_params.btm_set_cig_params.cis_count, p); - for (uint8_t i = 0; i < cb_params.btm_set_cig_params.cis_count; i++) + STREAM_TO_UINT8(cis_count, p); + + // Validate cis_count to prevent buffer overflow + if (cis_count > BLE_ISO_CIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, cis_count %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_count, BLE_ISO_CIS_MAX_COUNT); + cis_count = BLE_ISO_CIS_MAX_COUNT; + } + cb_params.btm_set_cig_params.cis_count = cis_count; + + for (uint8_t i = 0; i < cis_count; i++) { STREAM_TO_UINT16(cb_params.btm_set_cig_params.conn_hdl[i], p); BTM_TRACE_DEBUG("i = %d, conn_hdl = %d", i, cb_params.btm_set_cig_params.conn_hdl[i]); @@ -158,6 +167,8 @@ void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params) { BTM_TRACE_DEBUG("%s", __func__); tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + UINT8 num_bis; + if (!params) { BTM_TRACE_ERROR("%s, Invalid params.", __func__); return; @@ -167,6 +178,13 @@ void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params) params->status = (params->status | BTM_HCI_ERROR); } + // Validate num_bis to prevent buffer overflow + num_bis = params->num_bis; + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + num_bis = BLE_ISO_BIS_MAX_COUNT; + } + cb_params.btm_big_cmpl.status = params->status; cb_params.btm_big_cmpl.big_handle = params->big_handle; cb_params.btm_big_cmpl.big_sync_delay = params->big_sync_delay; @@ -178,14 +196,12 @@ void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params) cb_params.btm_big_cmpl.irc = params->irc; cb_params.btm_big_cmpl.max_pdu = params->max_pdu; cb_params.btm_big_cmpl.iso_interval = params->iso_interval; - cb_params.btm_big_cmpl.num_bis = params->num_bis; - // for (uint8_t i = 0; i < params->num_bis; i++) - // { - // cb_params.btm_big_cmpl.bis_handle[i] = params->bis_handle[i]; - // } - memcpy(&cb_params.btm_big_cmpl.bis_handle[0], ¶ms->bis_handle[0], params->num_bis * 2); + cb_params.btm_big_cmpl.num_bis = num_bis; - //memcpy(&cb_params.btm_big_cmpl, params, sizeof(tBTM_BLE_BIG_CREATE_CMPL)); + // Copy bis_handle array with bounds checking + if (num_bis > 0) { + memcpy(&cb_params.btm_big_cmpl.bis_handle[0], ¶ms->bis_handle[0], num_bis * sizeof(UINT16)); + } BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_CREATE_COMPLETE_EVT, &cb_params); } @@ -207,6 +223,8 @@ void btm_ble_big_terminate_cmpl_evt(tBTM_BLE_BIG_TERMINATE_CMPL *params) void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params) { tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + UINT8 num_bis; + if (!params) { BTM_TRACE_ERROR("%s, Invalid params.", __func__); return; @@ -216,7 +234,28 @@ void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params) params->status = (params->status | BTM_HCI_ERROR); } - memcpy(&cb_params.btm_big_sync_estab, params, sizeof(tBTM_BLE_BIG_SYNC_ESTAB_CMPL)); + // Validate num_bis to prevent buffer overflow + num_bis = params->num_bis; + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + num_bis = BLE_ISO_BIS_MAX_COUNT; + } + + cb_params.btm_big_sync_estab.status = params->status; + cb_params.btm_big_sync_estab.big_handle = params->big_handle; + cb_params.btm_big_sync_estab.transport_latency_big = params->transport_latency_big; + cb_params.btm_big_sync_estab.nse = params->nse; + cb_params.btm_big_sync_estab.bn = params->bn; + cb_params.btm_big_sync_estab.pto = params->pto; + cb_params.btm_big_sync_estab.irc = params->irc; + cb_params.btm_big_sync_estab.max_pdu = params->max_pdu; + cb_params.btm_big_sync_estab.iso_interval = params->iso_interval; + cb_params.btm_big_sync_estab.num_bis = num_bis; + + // Copy bis_handle array with bounds checking + if (num_bis > 0) { + memcpy(&cb_params.btm_big_sync_estab.bis_handle[0], ¶ms->bis_handle[0], num_bis * sizeof(uint16_t)); + } BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT, &cb_params); } @@ -286,6 +325,11 @@ tBTM_STATUS BTM_BleBigCreate(uint8_t big_handle, uint8_t adv_handle, uint8_t num rtn %d phy %d packing %d framing %d encryption %d broadcast_code %d", big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_transport_latency,\ rtn, phy, packing, framing, encryption, broadcast_code); + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + btsnd_hcic_ble_big_create(big_handle, adv_handle, num_bis, sdu_interval, max_sdu, max_transport_latency, rtn, phy, packing, framing, encryption, broadcast_code); @@ -299,6 +343,11 @@ tBTM_STATUS BTM_BleBigCreateTest(uint8_t big_handle, uint8_t adv_handle, uint8_t uint8_t packing, uint8_t framing, uint8_t bn, uint8_t irc, uint8_t pto, uint8_t encryption, uint8_t *broadcast_code) { + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + btsnd_hcic_ble_big_create_test(big_handle, adv_handle, num_bis, sdu_interval, iso_interval, nse, max_sdu, max_pdu, phy, packing, framing, bn, irc, pto, encryption, broadcast_code); @@ -331,6 +380,11 @@ tBTM_STATUS BTM_BleBigSyncCreate(uint8_t big_handle, uint16_t sync_handle, uint8_t mse, uint16_t big_sync_timeout, uint8_t num_bis, uint8_t *bis) { + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + btsnd_hcic_ble_big_sync_create(big_handle, sync_handle, encryption, bc_code, mse, big_sync_timeout, num_bis, bis); return BTM_SUCCESS; @@ -430,6 +484,11 @@ tBTM_STATUS BTM_BleSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_ tHCI_STATUS err = HCI_SUCCESS; tBTM_STATUS status = BTM_SUCCESS; + if (cis_cnt > BLE_ISO_CIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, cis_cnt %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_cnt, BLE_ISO_CIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + if ((err = btsnd_hcic_ble_iso_set_cig_params(cig_id, sdu_int_c_to_p, sdu_int_p_to_c, worse_case_SCA, packing, framing, mtl_c_to_p, mtl_p_to_c, cis_cnt, (struct ble_hci_le_cis_params *)cis_params)) != HCI_SUCCESS) { BTM_TRACE_ERROR("iso set cig params, cmd err=0x%x", err); @@ -445,6 +504,11 @@ tBTM_STATUS BTM_BleSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uin tHCI_STATUS err = HCI_SUCCESS; tBTM_STATUS status = BTM_SUCCESS; + if (cis_cnt > BLE_ISO_CIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, cis_cnt %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_cnt, BLE_ISO_CIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + if ((err = btsnd_hcic_ble_iso_set_cig_params_test(cig_id, sdu_int_c_to_p, sdu_int_p_to_c,ft_c_to_p, ft_p_to_c, iso_interval, worse_case_SCA, packing, framing, cis_cnt, (struct ble_hci_le_cis_params_test *)cis_params)) != HCI_SUCCESS) { BTM_TRACE_ERROR("iso set cig params test, cmd err=0x%x", err); @@ -461,6 +525,11 @@ void btm_ble_create_cis_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params) tBTM_STATUS BTM_BleCreateCis(uint8_t cis_count, uint8_t *cis_hdls) { + if (cis_count > BLE_ISO_CIS_MAX_COUNT) { + BTM_TRACE_ERROR("%s, cis_count %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_count, BLE_ISO_CIS_MAX_COUNT); + return BTM_ILLEGAL_VALUE; + } + btsnd_hcic_ble_iso_create_cis(cis_count, (struct ble_hci_cis_hdls *)cis_hdls); return BTM_SUCCESS; diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 22cc19e371..a1c36f71eb 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -52,6 +52,17 @@ extern void btm_process_cancel_complete(UINT8 status, UINT8 mode); extern void btm_ble_test_command_complete(UINT8 *p); +#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) +// BLE Channel Sounding parameter validation macros per BLE spec +#define BTM_BLE_CS_MAX_STEPS_REPORTED 0xA0 // Range: 0x00 to 0xA0 (0 to 160) +#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) + +#if (BLE_FEAT_CTE_EN == TRUE) +// BLE CTE parameter validation macros per BLE spec +#define BTM_BLE_CTE_MAX_SAMPLE_COUNT 0x52 // Maximum sample count per BLE spec: 0x52 (82) +#endif // (BLE_FEAT_CTE_EN == TRUE) + + /********************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /********************************************************************************/ @@ -2899,6 +2910,7 @@ static void btu_ble_big_create_complete_evt(UINT8 *p) { HCI_TRACE_DEBUG("%s", __func__); tBTM_BLE_BIG_CREATE_CMPL big_cmpl = {0}; + UINT8 num_bis; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -2916,8 +2928,16 @@ static void btu_ble_big_create_complete_evt(UINT8 *p) STREAM_TO_UINT8(big_cmpl.irc, p); STREAM_TO_UINT16(big_cmpl.max_pdu, p); STREAM_TO_UINT16(big_cmpl.iso_interval, p); - STREAM_TO_UINT8(big_cmpl.num_bis, p); - for (uint8_t i = 0; i < big_cmpl.num_bis; i++) + STREAM_TO_UINT8(num_bis, p); + + // Validate num_bis to prevent buffer overflow + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + HCI_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + num_bis = BLE_ISO_BIS_MAX_COUNT; + } + big_cmpl.num_bis = num_bis; + + for (uint8_t i = 0; i < num_bis; i++) { STREAM_TO_UINT16(big_cmpl.bis_handle[i], p); // only 12 bits meaningful @@ -2966,6 +2986,7 @@ void btu_ble_create_big_sync_cmd_status(UINT8 status) static void btu_ble_big_sync_establish_evt(UINT8 *p) { tBTM_BLE_BIG_SYNC_ESTAB_CMPL big_estb = {0}; + UINT8 num_bis; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -2981,8 +3002,16 @@ static void btu_ble_big_sync_establish_evt(UINT8 *p) STREAM_TO_UINT8(big_estb.irc, p); STREAM_TO_UINT16(big_estb.max_pdu, p); STREAM_TO_UINT16(big_estb.iso_interval, p); - STREAM_TO_UINT8(big_estb.num_bis, p); - for (uint8_t i = 0; i < big_estb.num_bis; i++) + STREAM_TO_UINT8(num_bis, p); + + // Validate num_bis to prevent buffer overflow + if (num_bis > BLE_ISO_BIS_MAX_COUNT) { + HCI_TRACE_ERROR("%s, num_bis %d exceeds BLE_ISO_BIS_MAX_COUNT %d", __func__, num_bis, BLE_ISO_BIS_MAX_COUNT); + num_bis = BLE_ISO_BIS_MAX_COUNT; + } + big_estb.num_bis = num_bis; + + for (uint8_t i = 0; i < num_bis; i++) { STREAM_TO_UINT16(big_estb.bis_handle[i], p); } @@ -3038,6 +3067,7 @@ static void btu_ble_biginfo_adv_report_evt(UINT8 *p) static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) { tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT connless_iq_rpt = {0}; + UINT8 sample_count; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -3052,14 +3082,21 @@ static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) STREAM_TO_UINT8(connless_iq_rpt.slot_dur, p); STREAM_TO_UINT8(connless_iq_rpt.pkt_status, p); STREAM_TO_UINT16(connless_iq_rpt.periodic_evt_counter, p); - STREAM_TO_UINT8(connless_iq_rpt.sample_count, p); + STREAM_TO_UINT8(sample_count, p); - for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++) + // Validate sample_count to prevent buffer overflow + if (sample_count > BTM_BLE_CTE_MAX_SAMPLE_COUNT) { + HCI_TRACE_ERROR("%s, sample_count %d exceeds maximum %d", __func__, sample_count, BTM_BLE_CTE_MAX_SAMPLE_COUNT); + sample_count = BTM_BLE_CTE_MAX_SAMPLE_COUNT; + } + connless_iq_rpt.sample_count = sample_count; + + for (uint8_t i = 0; i < sample_count; i++) { STREAM_TO_UINT8(connless_iq_rpt.i_sample[i], p); } - for (uint8_t i = 0; i < connless_iq_rpt.sample_count; i++) + for (uint8_t i = 0; i < sample_count; i++) { STREAM_TO_UINT8(connless_iq_rpt.q_sample[i], p); } @@ -3072,6 +3109,7 @@ static void btu_ble_cte_connless_iq_report_evt(UINT8 *p) static void btu_ble_cte_conn_iq_report_evt(UINT8 *p) { tBTM_BLE_CTE_CONN_IQ_REPORT_EVT conn_iq_rpt = {0}; + UINT8 sample_count; if (!p) { HCI_TRACE_ERROR("%s, Invalid params.", __func__); @@ -3087,14 +3125,21 @@ static void btu_ble_cte_conn_iq_report_evt(UINT8 *p) STREAM_TO_UINT8(conn_iq_rpt.slot_dur, p); STREAM_TO_UINT8(conn_iq_rpt.pkt_status, p); STREAM_TO_UINT16(conn_iq_rpt.conn_evt_counter, p); - STREAM_TO_UINT8(conn_iq_rpt.sample_count, p); + STREAM_TO_UINT8(sample_count, p); - for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++) + // Validate sample_count to prevent buffer overflow + if (sample_count > BTM_BLE_CTE_MAX_SAMPLE_COUNT) { + HCI_TRACE_ERROR("%s, sample_count %d exceeds maximum %d", __func__, sample_count, BTM_BLE_CTE_MAX_SAMPLE_COUNT); + sample_count = BTM_BLE_CTE_MAX_SAMPLE_COUNT; + } + conn_iq_rpt.sample_count = sample_count; + + for (uint8_t i = 0; i < sample_count; i++) { STREAM_TO_UINT8(conn_iq_rpt.i_sample[i], p); } - for (uint8_t i = 0; i < conn_iq_rpt.sample_count; i++) + for (uint8_t i = 0; i < sample_count; i++) { STREAM_TO_UINT8(conn_iq_rpt.q_sample[i], p); } @@ -3205,6 +3250,7 @@ static void btu_ble_pa_response_report_evt(UINT8 *p) STREAM_TO_UINT8(pa_rsp_rpt_evt.tx_status, p); STREAM_TO_UINT8(pa_rsp_rpt_evt.num_rsp, p); + // num_rsp is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate if (pa_rsp_rpt_evt.num_rsp) { pa_rsp_rpt_evt.rsp_data_info = osi_malloc(pa_rsp_rpt_evt.num_rsp * sizeof(tBTM_BLE_PA_RSP_DATA_INFO)); if (pa_rsp_rpt_evt.rsp_data_info) @@ -3217,17 +3263,21 @@ static void btu_ble_pa_response_report_evt(UINT8 *p) STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rsp_slot, p); STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_status, p); STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].data_len, p); + // data_len is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate if (pa_rsp_rpt_evt.rsp_data_info[i].data_len) { pa_rsp_rpt_evt.rsp_data_info[i].data = osi_malloc(pa_rsp_rpt_evt.rsp_data_info[i].data_len); if (pa_rsp_rpt_evt.rsp_data_info[i].data) { STREAM_TO_ARRAY(pa_rsp_rpt_evt.rsp_data_info[i].data, p, pa_rsp_rpt_evt.rsp_data_info[i].data_len); } else { - HCI_TRACE_ERROR("%s, no enough memory.", __func__); + HCI_TRACE_ERROR("%s, no enough memory for data_len %d at index %d", __func__, pa_rsp_rpt_evt.rsp_data_info[i].data_len, i); + pa_rsp_rpt_evt.rsp_data_info[i].data_len = 0; } + } else { + pa_rsp_rpt_evt.rsp_data_info[i].data = NULL; } } } else { - HCI_TRACE_ERROR("%s, no memory.", __func__); + HCI_TRACE_ERROR("%s, no memory for rsp_data_info", __func__); } } @@ -3387,7 +3437,15 @@ static void btu_ble_cs_subevt_result_evt(UINT8 *p) STREAM_TO_UINT8(subevt_result.subevent_done_status, p); STREAM_TO_UINT8(subevt_result.abort_reason, p); STREAM_TO_UINT8(subevt_result.num_ant_paths, p); - STREAM_TO_UINT8(subevt_result.num_steps_reported, p); + UINT8 num_steps_reported; + STREAM_TO_UINT8(num_steps_reported, p); + + // Validate num_steps_reported per BLE spec: Range 0x00 to 0xA0 (0 to 160) + if (num_steps_reported > BTM_BLE_CS_MAX_STEPS_REPORTED) { + HCI_TRACE_ERROR("%s, num_steps_reported %d exceeds maximum %d", __func__, num_steps_reported, BTM_BLE_CS_MAX_STEPS_REPORTED); + num_steps_reported = BTM_BLE_CS_MAX_STEPS_REPORTED; + } + subevt_result.num_steps_reported = num_steps_reported; subevt_result.step_info = osi_malloc(subevt_result.num_steps_reported * sizeof(tBTM_BLE_CS_STEP_INFO)); if (subevt_result.step_info) { @@ -3396,6 +3454,7 @@ static void btu_ble_cs_subevt_result_evt(UINT8 *p) STREAM_TO_UINT8(subevt_result.step_info[i].step_mode, p); STREAM_TO_UINT8(subevt_result.step_info[i].step_channel, p); STREAM_TO_UINT8(subevt_result.step_info[i].step_data_len, p); + // step_data_len is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate subevt_result.step_info[i].data = osi_malloc(subevt_result.step_info[i].step_data_len); if (subevt_result.step_info[i].data) { STREAM_TO_ARRAY(subevt_result.step_info[i].data, p, subevt_result.step_info[i].step_data_len); @@ -3435,7 +3494,15 @@ static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p) STREAM_TO_UINT8(subevt_continue_result.subevt_done_status, p); STREAM_TO_UINT8(subevt_continue_result.abort_reason, p); STREAM_TO_UINT8(subevt_continue_result.num_ant_paths, p); - STREAM_TO_UINT8(subevt_continue_result.num_steps_reported, p); + UINT8 num_steps_reported; + STREAM_TO_UINT8(num_steps_reported, p); + + // Validate num_steps_reported per BLE spec: Range 0x00 to 0xA0 (0 to 160) + if (num_steps_reported > BTM_BLE_CS_MAX_STEPS_REPORTED) { + HCI_TRACE_ERROR("%s, num_steps_reported %d exceeds maximum %d", __func__, num_steps_reported, BTM_BLE_CS_MAX_STEPS_REPORTED); + num_steps_reported = BTM_BLE_CS_MAX_STEPS_REPORTED; + } + subevt_continue_result.num_steps_reported = num_steps_reported; subevt_continue_result.step_info = osi_malloc(subevt_continue_result.num_steps_reported * sizeof(tBTM_BLE_CS_STEP_INFO)); if (subevt_continue_result.step_info) { @@ -3443,6 +3510,7 @@ static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p) STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_mode, p); STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_channel, p); STREAM_TO_UINT8(subevt_continue_result.step_info[i].step_data_len, p); + // step_data_len is UINT8, range 0x00 to 0xFF (0 to 255), no need to validate subevt_continue_result.step_info[i].data = osi_malloc(subevt_continue_result.step_info[i].step_data_len); if (subevt_continue_result.step_info[i].data) { STREAM_TO_ARRAY(subevt_continue_result.step_info[i].data, p, subevt_continue_result.step_info[i].step_data_len); diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 9ddbc6271a..fef574fd6a 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1731,7 +1731,6 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn_v2(tHCI_CreatExtConn *p_conn) UINT8_TO_STREAM(pp, p_conn->adv_handle); UINT8_TO_STREAM(pp, p_conn->subevent); UINT8_TO_STREAM(pp, p_conn->filter_policy); - UINT8_TO_STREAM(pp, p_conn->filter_policy); UINT8_TO_STREAM(pp, p_conn->own_addr_type); UINT8_TO_STREAM(pp, p_conn->peer_addr_type); BDADDR_TO_STREAM(pp, p_conn->peer_addr); @@ -2995,7 +2994,7 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_su esp_log_buffer_hex_internal("data", subevent_params[i].data, subevent_params[i].subevent_data_len, ESP_LOG_DEBUG); } - param_len += (4 + subevent_params->subevent_data_len); + param_len += (4 + subevent_params[i].subevent_data_len); } HCIC_BLE_CMD_CREATED(p, pp, param_len);