fix(ble/bluedroid): fix HCI command and BTU robustness

(cherry picked from commit c9d13aaf64)

Co-authored-by: zhiweijian <zhiweijian@espressif.com>
This commit is contained in:
Zhi Wei Jian
2026-06-10 19:53:49 +08:00
parent bb338161b9
commit a70431cac3
3 changed files with 47 additions and 7 deletions

View File

@@ -50,7 +50,7 @@
#include "stack/btu.h"
extern void btm_process_cancel_complete(UINT8 status, UINT8 mode);
extern void btm_ble_test_command_complete(UINT8 *p);
extern void btm_ble_test_command_complete(UINT8 *p, UINT16 len);
#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE)
// BLE Channel Sounding parameter validation macros per BLE spec
@@ -1331,11 +1331,17 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
btm_ble_create_ll_conn_complete(*p);
break;
#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
case HCI_BLE_TRANSMITTER_TEST:
case HCI_BLE_RECEIVER_TEST:
case HCI_BLE_TEST_END:
/* Forward raw parameters + length; upper layers validate before parsing. */
btm_ble_test_command_complete(p, evt_len);
break;
#else
case HCI_BLE_TRANSMITTER_TEST:
case HCI_BLE_RECEIVER_TEST:
#if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
case HCI_BLE_TEST_END:
btm_ble_test_command_complete(p);
break;
#endif // #if ((BLE_42_DTM_TEST_EN == TRUE) || (BLE_50_DTM_TEST_EN == TRUE))
case HCI_BLE_CREATE_CONN_CANCEL:
@@ -1397,7 +1403,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
#if (BLE_50_DTM_TEST_EN == TRUE)
case HCI_BLE_ENH_RX_TEST:
case HCI_BLE_ENH_TX_TEST:
btm_ble_test_command_complete(p);
btm_ble_test_command_complete(p, evt_len);
break;
#endif // #if (BLE_50_DTM_TEST_EN == TRUE)

View File

@@ -3059,7 +3059,8 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_su
{
BT_HDR *p;
UINT8 *pp;
uint8_t param_len = 0;
unsigned total_len;
UINT8 param_len;
HCI_TRACE_DEBUG("hci set PA subevent data, adv_handle %d num_subevents_with_data %d", adv_handle, num_subevents_with_data);
@@ -3067,10 +3068,19 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_subevt_data(UINT8 adv_handle, UINT8 num_su
HCI_TRACE_ERROR("%s error\n", __func__);
return HCI_ERR_ILLEGAL_PARAMETER_FMT;
}
param_len += HCIC_PARAM_SIZE_SET_PA_SUBEVT_DATA_PARAMS_LEN;
total_len = HCIC_PARAM_SIZE_SET_PA_SUBEVT_DATA_PARAMS_LEN;
for (UINT8 i = 0; i < num_subevents_with_data; i++)
{
if (subevent_params[i].subevent_data_len > sizeof(subevent_params[i].data)) {
HCI_TRACE_ERROR("%s sub_data_len %u>%u", __func__,
(unsigned)subevent_params[i].subevent_data_len,
(unsigned)sizeof(subevent_params[i].data));
return HCI_ERR_ILLEGAL_PARAMETER_FMT;
}
unsigned add_len = 4u + (unsigned)subevent_params[i].subevent_data_len;
HCI_TRACE_DEBUG("subevent_params: subevent %d response_slot_start %d response_slot_count %d subevent_data_len %d",
subevent_params[i].subevent, subevent_params[i].response_slot_start, subevent_params[i].response_slot_count,
subevent_params[i].subevent_data_len);
@@ -3079,9 +3089,17 @@ 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[i].subevent_data_len);
/* Avoid unsigned wrap when add_len > HCI_COMMAND_SIZE. */
if (total_len > (unsigned)HCI_COMMAND_SIZE ||
add_len > (unsigned)HCI_COMMAND_SIZE - total_len) {
HCI_TRACE_ERROR("%s total>HCI_CMD_SZ", __func__);
return HCI_ERR_ILLEGAL_PARAMETER_FMT;
}
total_len += add_len;
}
param_len = (UINT8)total_len;
HCIC_BLE_CMD_CREATED_U8(p, pp, param_len);
pp = (UINT8 *)(p + 1);
@@ -3113,6 +3131,11 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_rsp_data(UINT16 sync_handle, UINT16 req_ev
HCI_TRACE_DEBUG("hci set PA rsp data, sync_handle %d req_evt %d req_subevt %d rsp_subevt %d rsp_slot %d rsp_data_len %d",
sync_handle, req_evt, req_subevt, rsp_subevt, rsp_slot, rsp_data_len);
if (rsp_data_len > HCIC_PA_RSP_DATA_PAYLOAD_MAX) {
HCI_TRACE_ERROR("%s rsp_len %u>%u", __func__, rsp_data_len, HCIC_PA_RSP_DATA_PAYLOAD_MAX);
return HCI_ERR_ILLEGAL_PARAMETER_FMT;
}
HCIC_BLE_CMD_CREATED_U8(p, pp, HCIC_PARAM_SIZE_SET_PA_RESPONSE_DATA_PARAMS_LEN + rsp_data_len);
pp = (UINT8 *)(p + 1);
@@ -3141,6 +3164,12 @@ UINT8 btsnd_hcic_ble_set_periodic_sync_subevt(UINT16 sync_handle, UINT16 periodi
HCI_TRACE_DEBUG("hci set PA sync subevent, sync_handle %d periodic_adv_properties %d num_subevents_to_sync %d",
sync_handle, periodic_adv_properties, num_subevents_to_sync);
if (num_subevents_to_sync > HCIC_PA_SYNC_SUBEVT_NUM_MAX) {
HCI_TRACE_ERROR("%s n_sync %u>%u", __func__, num_subevents_to_sync, HCIC_PA_SYNC_SUBEVT_NUM_MAX);
return HCI_ERR_ILLEGAL_PARAMETER_FMT;
}
for (UINT8 i = 0; i < num_subevents_to_sync; i++)
{
HCI_TRACE_DEBUG("subevt[%d] = %d", i, subevt[i]);

View File

@@ -1285,6 +1285,11 @@ typedef struct {
#define HCIC_PARAM_SIZE_SET_PA_RESPONSE_DATA_PARAMS_LEN 8
#define HCIC_PARAM_SIZE_SET_PA_SYNC_SUBEVT_PARAMS_LEN 5
/** Max rsp_data octets in LE Set Periodic Advertising Response Data (HCI command param total ≤ HCI_COMMAND_SIZE). */
#define HCIC_PA_RSP_DATA_PAYLOAD_MAX (HCI_COMMAND_SIZE - HCIC_PARAM_SIZE_SET_PA_RESPONSE_DATA_PARAMS_LEN)
/** Max Num_Subevents_To_Sync in LE Set Periodic Advertising Sync Subevents (BT Core Spec §7.8.127: 0x010x80). */
#define HCIC_PA_SYNC_SUBEVT_NUM_MAX 128
#define HCIC_PARAM_SIZE_SET_PERIODIC_ADV_PARAMS_V2 12
UINT8 btsnd_hcic_ble_set_periodic_adv_params_v2(UINT8 adv_handle, UINT16 interval_min, UINT16 interval_max,
UINT16 propertics, UINT8 num_subevents, UINT8 subevent_interval,