mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
fix(ble/bluedroid): Event length checks and timer/alarm error handling
- btu_hcif: validate p_msg->len and hci_evt_len in process_event; pass evt_len to sub-handlers; fix cs_subevt num_steps_reported==0 malloc; bounds in command_complete and role_change_evt - btu_task: handle osi_alarm_new/hash_map_set failure in btu_start_timer, btu_start_quick_timer, btu_start_timer_oneshot
This commit is contained in:
@@ -100,7 +100,7 @@ static void btu_hcif_hardware_error_evt (UINT8 *p);
|
||||
static void btu_hcif_flush_occured_evt (void);
|
||||
static void btu_hcif_role_change_evt (UINT8 *p);
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
static void btu_hcif_num_compl_data_pkts_evt (UINT8 *p);
|
||||
static void btu_hcif_num_compl_data_pkts_evt (UINT8 *p, UINT8 evt_len);
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
static void btu_hcif_mode_change_evt (UINT8 *p);
|
||||
@@ -194,14 +194,14 @@ static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p);
|
||||
|
||||
#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
|
||||
void btu_ble_create_big_cmd_status(UINT8 status);
|
||||
static void btu_ble_big_create_complete_evt(UINT8 *p);
|
||||
static void btu_ble_big_create_complete_evt(UINT8 *p, UINT8 evt_len);
|
||||
void btu_ble_big_terminate_cmd_status(UINT8 status);
|
||||
static void btu_ble_big_terminate_complete_evt(UINT8 *p);
|
||||
#endif // #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
|
||||
|
||||
#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
|
||||
static void btu_ble_create_big_sync_cmd_status(UINT8 status);
|
||||
static void btu_ble_big_sync_establish_evt(UINT8 *p);
|
||||
static void btu_ble_big_sync_establish_evt(UINT8 *p, UINT8 evt_len);
|
||||
static void btu_ble_big_sync_lost_evt(UINT8 *p);
|
||||
static void btu_ble_biginfo_adv_report_evt(UINT8 *p);
|
||||
#endif // #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
|
||||
@@ -222,10 +222,10 @@ static void btu_ble_cis_disconnected(UINT16 handle, UINT8 reason);
|
||||
|
||||
#if (BLE_FEAT_CTE_EN == TRUE)
|
||||
#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
|
||||
static void btu_ble_cte_connless_iq_report_evt(UINT8 *p);
|
||||
static void btu_ble_cte_connless_iq_report_evt(UINT8 *p, UINT8 evt_len);
|
||||
#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
|
||||
#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
|
||||
static void btu_ble_cte_conn_iq_report_evt(UINT8 *p);
|
||||
static void btu_ble_cte_conn_iq_report_evt(UINT8 *p, UINT8 evt_len);
|
||||
static void btu_ble_cte_req_failed_evt(UINT8 *p);
|
||||
#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
|
||||
#endif // #if (BLE_FEAT_CTE_EN == TRUE)
|
||||
@@ -241,7 +241,7 @@ static void btu_ble_subrate_change_evt(UINT8 *p);
|
||||
|
||||
#if (BT_BLE_FEAT_PAWR_EN == TRUE)
|
||||
static void btu_ble_pa_subevt_data_request_evt(UINT8 *p);
|
||||
static void btu_ble_pa_response_report_evt(UINT8 *p);
|
||||
static void btu_ble_pa_response_report_evt(UINT8 *p, UINT8 evt_len);
|
||||
#endif // (BT_BLE_FEAT_PAWR_EN == TRUE)
|
||||
|
||||
#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE)
|
||||
@@ -250,8 +250,8 @@ static void btu_ble_cs_read_remote_fae_tab_evt(UINT8 *p);
|
||||
static void btu_ble_cs_security_enable_cmpl_evt(UINT8 *p);
|
||||
static void btu_ble_cs_config_cmpl_evt(UINT8 *p);
|
||||
static void btu_ble_cs_proc_enable_cmpl_evt(UINT8 *p);
|
||||
static void btu_ble_cs_subevt_result_evt(UINT8 *p);
|
||||
static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p);
|
||||
static void btu_ble_cs_subevt_result_evt(UINT8 *p, UINT8 evt_len);
|
||||
static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p, UINT8 evt_len);
|
||||
#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE)
|
||||
|
||||
#if (BLE_42_ADV_EN == TRUE)
|
||||
@@ -287,9 +287,20 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
#if BLE_INCLUDED == TRUE
|
||||
UINT8 ble_sub_code;
|
||||
#endif
|
||||
if (p_msg->len < 2) {
|
||||
HCI_TRACE_ERROR("%s: HCI event too short (len=%u), dropping", __func__, p_msg->len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT8 (hci_evt_code, p);
|
||||
STREAM_TO_UINT8 (hci_evt_len, p);
|
||||
|
||||
if (hci_evt_len > p_msg->len - 2) {
|
||||
HCI_TRACE_ERROR("%s: HCI evt 0x%02x param len %u exceeds buffer (avail=%u), dropping",
|
||||
__func__, hci_evt_code, hci_evt_len, p_msg->len - 2);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (hci_evt_code) {
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
case HCI_INQUIRY_COMP_EVT:
|
||||
@@ -372,7 +383,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
break;
|
||||
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
case HCI_NUM_COMPL_DATA_PKTS_EVT:
|
||||
btu_hcif_num_compl_data_pkts_evt (p);
|
||||
btu_hcif_num_compl_data_pkts_evt (p, hci_evt_len);
|
||||
break;
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
case HCI_MODE_CHANGE_EVT:
|
||||
@@ -469,6 +480,10 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
case HCI_BLE_EVENT:
|
||||
if (hci_evt_len < 1) {
|
||||
HCI_TRACE_ERROR("%s: BLE meta event param len %u invalid (need >= 1), dropping", __func__, hci_evt_len);
|
||||
break;
|
||||
}
|
||||
STREAM_TO_UINT8 (ble_sub_code, p);
|
||||
hci_evt_len--;
|
||||
HCI_TRACE_DEBUG("BLE HCI(id=%d) event = 0x%02x)", hci_evt_code, ble_sub_code);
|
||||
@@ -572,7 +587,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
#endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE)
|
||||
#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
|
||||
case HCI_BLE_BIG_CREATE_COMPLETE_EVT:
|
||||
btu_ble_big_create_complete_evt(p);
|
||||
btu_ble_big_create_complete_evt(p, hci_evt_len);
|
||||
break;
|
||||
case HCI_BLE_BIG_TERMINATE_COMPLETE_EVT:
|
||||
btu_ble_big_terminate_complete_evt(p);
|
||||
@@ -580,7 +595,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
#endif // #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
|
||||
#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
|
||||
case HCI_BLE_BIG_SYNC_ESTABLISHED_EVT:
|
||||
btu_ble_big_sync_establish_evt(p);
|
||||
btu_ble_big_sync_establish_evt(p, hci_evt_len);
|
||||
break;
|
||||
case HCI_BLE_BIG_SYNC_LOST_EVT:
|
||||
btu_ble_big_sync_lost_evt(p);
|
||||
@@ -593,13 +608,13 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
#if (BLE_FEAT_CTE_EN == TRUE)
|
||||
#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
|
||||
case HCI_BLE_CONNLESS_IQ_REPORT_EVT:
|
||||
btu_ble_cte_connless_iq_report_evt(p);
|
||||
btu_ble_cte_connless_iq_report_evt(p, hci_evt_len);
|
||||
break;
|
||||
#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
|
||||
|
||||
#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
|
||||
case HCI_BLE_CONN_IQ_REPORT_EVT:
|
||||
btu_ble_cte_conn_iq_report_evt(p);
|
||||
btu_ble_cte_conn_iq_report_evt(p, hci_evt_len);
|
||||
break;
|
||||
case HCI_BLE_CTE_REQUEST_FAILED_EVT:
|
||||
btu_ble_cte_req_failed_evt(p);
|
||||
@@ -625,7 +640,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
btu_ble_pa_subevt_data_request_evt(p);
|
||||
break;
|
||||
case HCI_BLE_PA_RESPONSE_REPORT_EVT:
|
||||
btu_ble_pa_response_report_evt(p);
|
||||
btu_ble_pa_response_report_evt(p, hci_evt_len);
|
||||
break;
|
||||
#endif // #if (BT_BLE_FEAT_PAWR_EN == TRUE)
|
||||
#if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE)
|
||||
@@ -645,10 +660,10 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
btu_ble_cs_proc_enable_cmpl_evt(p);
|
||||
break;
|
||||
case HCI_BLE_CS_SUBEVENT_RESULT_EVT:
|
||||
btu_ble_cs_subevt_result_evt(p);
|
||||
btu_ble_cs_subevt_result_evt(p, hci_evt_len);
|
||||
break;
|
||||
case HCI_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT:
|
||||
btu_ble_cs_subevt_result_continue_evt(p);
|
||||
btu_ble_cs_subevt_result_continue_evt(p, hci_evt_len);
|
||||
break;
|
||||
#endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE)
|
||||
}
|
||||
@@ -1410,7 +1425,7 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
|
||||
#if (BLE_FEAT_ISO_EN == TRUE)
|
||||
#if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE)
|
||||
case HCI_BLE_BIG_TERMINATE_SYNC:
|
||||
UINT16 big_handle;
|
||||
UINT8 big_handle;
|
||||
STREAM_TO_UINT8(status, p);
|
||||
STREAM_TO_UINT8(big_handle, p);
|
||||
btm_ble_big_sync_terminate_complete(status, big_handle);
|
||||
@@ -1936,14 +1951,14 @@ static void btu_hcif_role_change_evt (UINT8 *p)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_num_compl_data_pkts_evt (UINT8 *p)
|
||||
static void btu_hcif_num_compl_data_pkts_evt (UINT8 *p, UINT8 evt_len)
|
||||
{
|
||||
/* Process for L2CAP and SCO */
|
||||
l2c_link_process_num_completed_pkts (p);
|
||||
l2c_link_process_num_completed_pkts (p, evt_len);
|
||||
|
||||
/* Send on to SCO */
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTM_SCO_INCLUDED == TRUE)
|
||||
btm_sco_process_num_completed_pkts (p);
|
||||
btm_sco_process_num_completed_pkts (p, evt_len);
|
||||
#endif
|
||||
}
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
@@ -2564,19 +2579,36 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
|
||||
UINT16 evt_type = 0;
|
||||
uint8_t addr_type;
|
||||
BD_ADDR bda;
|
||||
UINT16 remaining;
|
||||
|
||||
if (!p) {
|
||||
HCI_TRACE_ERROR("%s, Invalid params.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt_len < 1) {
|
||||
HCI_TRACE_ERROR("%s, evt_len too short (%u)", __func__, evt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT8(num_reports, p);
|
||||
remaining = evt_len - 1;
|
||||
|
||||
if (num_reports == 0) {
|
||||
HCI_TRACE_ERROR("%s, Invalid number reports is 0", __func__);
|
||||
}
|
||||
|
||||
/* Per-report fixed fields: evt_type(2) + addr_type(1) + bda(6) +
|
||||
* primary_phy(1) + secondary_phy(1) + sid(1) + tx_power(1) + rssi(1) +
|
||||
* per_adv_interval(2) + dir_addr_type(1) + dir_addr(6) + adv_data_len(1) = 24 */
|
||||
#define EXT_ADV_RPT_FIXED_LEN 24
|
||||
|
||||
while (num_reports--) {
|
||||
if (remaining < EXT_ADV_RPT_FIXED_LEN) {
|
||||
HCI_TRACE_ERROR("%s, remaining %u too short for report (need %u)",
|
||||
__func__, remaining, EXT_ADV_RPT_FIXED_LEN);
|
||||
return;
|
||||
}
|
||||
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
|
||||
/* Save current report start position for address resolution callback */
|
||||
pp = p;
|
||||
@@ -2624,6 +2656,14 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
|
||||
STREAM_TO_UINT8(ext_adv_report.dir_addr_type, p);
|
||||
STREAM_TO_BDADDR(ext_adv_report.dir_addr, p);
|
||||
STREAM_TO_UINT8(ext_adv_report.adv_data_len, p);
|
||||
remaining -= EXT_ADV_RPT_FIXED_LEN;
|
||||
|
||||
if (ext_adv_report.adv_data_len > remaining) {
|
||||
HCI_TRACE_ERROR("%s, adv_data_len %u exceeds remaining %u",
|
||||
__func__, ext_adv_report.adv_data_len, remaining);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ext_adv_report.adv_data_len) {
|
||||
ext_adv_report.adv_data = p;
|
||||
} else {
|
||||
@@ -2632,6 +2672,7 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
|
||||
|
||||
btm_ble_ext_adv_report_evt(&ext_adv_report);
|
||||
p += ext_adv_report.adv_data_len;
|
||||
remaining -= ext_adv_report.adv_data_len;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2948,7 +2989,7 @@ void btu_ble_create_big_cmd_status(UINT8 status)
|
||||
}
|
||||
}
|
||||
|
||||
static void btu_ble_big_create_complete_evt(UINT8 *p)
|
||||
static void btu_ble_big_create_complete_evt(UINT8 *p, UINT8 evt_len)
|
||||
{
|
||||
HCI_TRACE_DEBUG("%s", __func__);
|
||||
tBTM_BLE_BIG_CREATE_CMPL big_cmpl = {0};
|
||||
@@ -2959,6 +3000,15 @@ static void btu_ble_big_create_complete_evt(UINT8 *p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fixed fields: status(1) + big_handle(1) + big_sync_delay(3)
|
||||
* + transport_latency(3) + phy(1) + nse(1) + bn(1) + pto(1) + irc(1)
|
||||
* + max_pdu(2) + iso_interval(2) + num_bis(1) = 18 bytes
|
||||
* (subevent_code already subtracted from evt_len by caller) */
|
||||
if (evt_len < 18) {
|
||||
HCI_TRACE_ERROR("%s, evt too short (len=%u, need>=18)", __func__, evt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT8(big_cmpl.status, p);
|
||||
STREAM_TO_UINT8(big_cmpl.big_handle, p);
|
||||
STREAM_TO_UINT24(big_cmpl.big_sync_delay, p);
|
||||
@@ -2972,11 +3022,14 @@ static void btu_ble_big_create_complete_evt(UINT8 *p)
|
||||
STREAM_TO_UINT16(big_cmpl.iso_interval, p);
|
||||
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;
|
||||
}
|
||||
if (num_bis > (evt_len - 18) / 2) {
|
||||
HCI_TRACE_ERROR("%s, num_bis %d exceeds evt_len %u, truncating", __func__, num_bis, evt_len);
|
||||
num_bis = (evt_len - 18) / 2;
|
||||
}
|
||||
big_cmpl.num_bis = num_bis;
|
||||
|
||||
for (uint8_t i = 0; i < num_bis; i++)
|
||||
@@ -3025,7 +3078,7 @@ void btu_ble_create_big_sync_cmd_status(UINT8 status)
|
||||
}
|
||||
}
|
||||
|
||||
static void btu_ble_big_sync_establish_evt(UINT8 *p)
|
||||
static void btu_ble_big_sync_establish_evt(UINT8 *p, UINT8 evt_len)
|
||||
{
|
||||
tBTM_BLE_BIG_SYNC_ESTAB_CMPL big_estb = {0};
|
||||
UINT8 num_bis;
|
||||
@@ -3035,6 +3088,15 @@ static void btu_ble_big_sync_establish_evt(UINT8 *p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fixed fields: status(1) + big_handle(1) + transport_latency_big(3)
|
||||
* + nse(1) + bn(1) + pto(1) + irc(1) + max_pdu(2) + iso_interval(2)
|
||||
* + num_bis(1) = 14 bytes
|
||||
* (subevent_code already subtracted from evt_len by caller) */
|
||||
if (evt_len < 14) {
|
||||
HCI_TRACE_ERROR("%s, evt too short (len=%u, need>=14)", __func__, evt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT8(big_estb.status, p);
|
||||
STREAM_TO_UINT8(big_estb.big_handle, p);
|
||||
STREAM_TO_UINT24(big_estb.transport_latency_big, p);
|
||||
@@ -3046,11 +3108,14 @@ static void btu_ble_big_sync_establish_evt(UINT8 *p)
|
||||
STREAM_TO_UINT16(big_estb.iso_interval, p);
|
||||
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;
|
||||
}
|
||||
if (num_bis > (evt_len - 14) / 2) {
|
||||
HCI_TRACE_ERROR("%s, num_bis %d exceeds evt_len %u, truncating", __func__, num_bis, evt_len);
|
||||
num_bis = (evt_len - 14) / 2;
|
||||
}
|
||||
big_estb.num_bis = num_bis;
|
||||
|
||||
for (uint8_t i = 0; i < num_bis; i++)
|
||||
@@ -3106,7 +3171,7 @@ static void btu_ble_biginfo_adv_report_evt(UINT8 *p)
|
||||
|
||||
#if (BLE_FEAT_CTE_EN == TRUE)
|
||||
#if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
|
||||
static void btu_ble_cte_connless_iq_report_evt(UINT8 *p)
|
||||
static void btu_ble_cte_connless_iq_report_evt(UINT8 *p, UINT8 evt_len)
|
||||
{
|
||||
tBTM_BLE_CTE_CONNLESS_IQ_REPORT_EVT connless_iq_rpt = {0};
|
||||
UINT8 sample_count;
|
||||
@@ -3116,6 +3181,15 @@ static void btu_ble_cte_connless_iq_report_evt(UINT8 *p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fixed fields: sync_handle(2) + channel_idx(1) + rssi(2)
|
||||
* + rssi_ant_id(1) + cte_type(1) + slot_dur(1) + pkt_status(1)
|
||||
* + periodic_evt_counter(2) + sample_count(1) = 12 bytes
|
||||
* (subevent_code already subtracted from evt_len by caller) */
|
||||
if (evt_len < 12) {
|
||||
HCI_TRACE_ERROR("%s, evt too short (len=%u, need>=12)", __func__, evt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT16(connless_iq_rpt.sync_handle, p);
|
||||
STREAM_TO_UINT8(connless_iq_rpt.channel_idx, p);
|
||||
STREAM_TO_UINT16(connless_iq_rpt.rssi, p);
|
||||
@@ -3126,11 +3200,14 @@ static void btu_ble_cte_connless_iq_report_evt(UINT8 *p)
|
||||
STREAM_TO_UINT16(connless_iq_rpt.periodic_evt_counter, p);
|
||||
STREAM_TO_UINT8(sample_count, p);
|
||||
|
||||
// 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;
|
||||
}
|
||||
if (sample_count > (evt_len - 12) / 2) {
|
||||
HCI_TRACE_ERROR("%s, sample_count %d exceeds evt_len %u, truncating", __func__, sample_count, evt_len);
|
||||
sample_count = (evt_len - 12) / 2;
|
||||
}
|
||||
connless_iq_rpt.sample_count = sample_count;
|
||||
|
||||
for (uint8_t i = 0; i < sample_count; i++)
|
||||
@@ -3148,7 +3225,7 @@ static void btu_ble_cte_connless_iq_report_evt(UINT8 *p)
|
||||
#endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE)
|
||||
|
||||
#if (BLE_FEAT_CTE_CONNECTION_EN == TRUE)
|
||||
static void btu_ble_cte_conn_iq_report_evt(UINT8 *p)
|
||||
static void btu_ble_cte_conn_iq_report_evt(UINT8 *p, UINT8 evt_len)
|
||||
{
|
||||
tBTM_BLE_CTE_CONN_IQ_REPORT_EVT conn_iq_rpt = {0};
|
||||
UINT8 sample_count;
|
||||
@@ -3158,6 +3235,15 @@ static void btu_ble_cte_conn_iq_report_evt(UINT8 *p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fixed fields: conn_handle(2) + rx_phy(1) + data_channel_idx(1)
|
||||
* + rssi(2) + rssi_ant_id(1) + cte_type(1) + slot_dur(1) + pkt_status(1)
|
||||
* + conn_evt_counter(2) + sample_count(1) = 13 bytes
|
||||
* (subevent_code already subtracted from evt_len by caller) */
|
||||
if (evt_len < 13) {
|
||||
HCI_TRACE_ERROR("%s, evt too short (len=%u, need>=13)", __func__, evt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT16(conn_iq_rpt.conn_handle, p);
|
||||
STREAM_TO_UINT8(conn_iq_rpt.rx_phy, p);
|
||||
STREAM_TO_UINT8(conn_iq_rpt.data_channel_idx, p);
|
||||
@@ -3169,11 +3255,14 @@ static void btu_ble_cte_conn_iq_report_evt(UINT8 *p)
|
||||
STREAM_TO_UINT16(conn_iq_rpt.conn_evt_counter, p);
|
||||
STREAM_TO_UINT8(sample_count, p);
|
||||
|
||||
// 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;
|
||||
}
|
||||
if (sample_count > (evt_len - 13) / 2) {
|
||||
HCI_TRACE_ERROR("%s, sample_count %d exceeds evt_len %u, truncating", __func__, sample_count, evt_len);
|
||||
sample_count = (evt_len - 13) / 2;
|
||||
}
|
||||
conn_iq_rpt.sample_count = sample_count;
|
||||
|
||||
for (uint8_t i = 0; i < sample_count; i++)
|
||||
@@ -3279,7 +3368,7 @@ static void btu_ble_pa_subevt_data_request_evt(UINT8 *p)
|
||||
btm_ble_pa_subevt_data_req_evt(&pa_subevt_req_evt);
|
||||
}
|
||||
|
||||
static void btu_ble_pa_response_report_evt(UINT8 *p)
|
||||
static void btu_ble_pa_response_report_evt(UINT8 *p, UINT8 evt_len)
|
||||
{
|
||||
tBTM_BLE_PA_RSP_REPORT_EVT pa_rsp_rpt_evt = {0};
|
||||
if (!p) {
|
||||
@@ -3287,33 +3376,58 @@ static void btu_ble_pa_response_report_evt(UINT8 *p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fixed fields: adv_handle(1) + subevt(1) + tx_status(1) + num_rsp(1) = 4 bytes
|
||||
* (subevent_code already subtracted from evt_len by caller) */
|
||||
if (evt_len < 4) {
|
||||
HCI_TRACE_ERROR("%s, evt too short (len=%u, need>=4)", __func__, evt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT8(pa_rsp_rpt_evt.adv_handle, p);
|
||||
STREAM_TO_UINT8(pa_rsp_rpt_evt.subevt, 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
|
||||
UINT8 remaining = evt_len - 4;
|
||||
|
||||
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)
|
||||
{
|
||||
for (UINT8 i = 0; i < pa_rsp_rpt_evt.num_rsp; i++)
|
||||
{
|
||||
/* Per-response fixed: tx_power(1)+rssi(1)+cte_type(1)+rsp_slot(1)+data_status(1)+data_len(1) = 6 */
|
||||
if (remaining < 6) {
|
||||
HCI_TRACE_ERROR("%s, remaining %u too short for response %d", __func__, remaining, i);
|
||||
pa_rsp_rpt_evt.num_rsp = i;
|
||||
break;
|
||||
}
|
||||
STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].tx_power, p);
|
||||
STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].rssi, p);
|
||||
STREAM_TO_UINT8(pa_rsp_rpt_evt.rsp_data_info[i].cte_type, 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
|
||||
remaining -= 6;
|
||||
if (pa_rsp_rpt_evt.rsp_data_info[i].data_len > remaining) {
|
||||
HCI_TRACE_ERROR("%s, data_len %d exceeds remaining %u at index %d",
|
||||
__func__, pa_rsp_rpt_evt.rsp_data_info[i].data_len, remaining, i);
|
||||
pa_rsp_rpt_evt.rsp_data_info[i].data_len = 0;
|
||||
pa_rsp_rpt_evt.rsp_data_info[i].data = NULL;
|
||||
pa_rsp_rpt_evt.num_rsp = i + 1;
|
||||
break;
|
||||
}
|
||||
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 for data_len %d at index %d", __func__, pa_rsp_rpt_evt.rsp_data_info[i].data_len, i);
|
||||
p += pa_rsp_rpt_evt.rsp_data_info[i].data_len;
|
||||
remaining -= pa_rsp_rpt_evt.rsp_data_info[i].data_len;
|
||||
pa_rsp_rpt_evt.rsp_data_info[i].data_len = 0;
|
||||
}
|
||||
remaining -= pa_rsp_rpt_evt.rsp_data_info[i].data_len;
|
||||
} else {
|
||||
pa_rsp_rpt_evt.rsp_data_info[i].data = NULL;
|
||||
}
|
||||
@@ -3462,13 +3576,25 @@ static void btu_ble_cs_proc_enable_cmpl_evt(UINT8 *p)
|
||||
btm_ble_cs_proc_enable_cmpl_evt(&proc_en);
|
||||
}
|
||||
|
||||
static void btu_ble_cs_subevt_result_evt(UINT8 *p)
|
||||
static void btu_ble_cs_subevt_result_evt(UINT8 *p, UINT8 evt_len)
|
||||
{
|
||||
tBTM_BLE_CS_SUBEVT_RESULT_CMPL_EVT subevt_result = {0};
|
||||
if (!p) {
|
||||
HCI_TRACE_ERROR("%s, Invalid params.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fixed fields: conn_handle(2) + config_id(1) +
|
||||
* start_acl_conn_event_counter(2) + procedure_counter(2) +
|
||||
* frequency_compensation(2) + reference_power_level(1) +
|
||||
* procedure_done_status(1) + subevent_done_status(1) + abort_reason(1) +
|
||||
* num_ant_paths(1) + num_steps_reported(1) = 15 bytes
|
||||
* (subevent_code already subtracted from evt_len by caller) */
|
||||
if (evt_len < 15) {
|
||||
HCI_TRACE_ERROR("%s, evt too short (len=%u, need>=15)", __func__, evt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT16(subevt_result.conn_handle, p);
|
||||
STREAM_TO_UINT8(subevt_result.config_id, p);
|
||||
STREAM_TO_UINT16(subevt_result.start_acl_conn_event_counter, p);
|
||||
@@ -3482,27 +3608,49 @@ static void btu_ble_cs_subevt_result_evt(UINT8 *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) {
|
||||
UINT8 remaining = evt_len - 15;
|
||||
subevt_result.step_info = (subevt_result.num_steps_reported > 0)
|
||||
? osi_malloc(subevt_result.num_steps_reported * sizeof(tBTM_BLE_CS_STEP_INFO))
|
||||
: NULL;
|
||||
if (subevt_result.step_info || subevt_result.num_steps_reported == 0) {
|
||||
for (uint8_t i = 0; i < subevt_result.num_steps_reported; i++)
|
||||
{
|
||||
/* Per-step fixed: step_mode(1) + step_channel(1) + step_data_len(1) = 3 */
|
||||
if (remaining < 3) {
|
||||
HCI_TRACE_ERROR("%s, remaining %u too short for step %d", __func__, remaining, i);
|
||||
subevt_result.num_steps_reported = i;
|
||||
break;
|
||||
}
|
||||
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
|
||||
remaining -= 3;
|
||||
if (subevt_result.step_info[i].step_data_len > remaining) {
|
||||
HCI_TRACE_ERROR("%s, step_data_len %d exceeds remaining %u at step %d",
|
||||
__func__, subevt_result.step_info[i].step_data_len, remaining, i);
|
||||
subevt_result.step_info[i].step_data_len = 0;
|
||||
subevt_result.step_info[i].data = NULL;
|
||||
subevt_result.num_steps_reported = i + 1;
|
||||
break;
|
||||
}
|
||||
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);
|
||||
} else if (subevt_result.step_info[i].step_data_len) {
|
||||
HCI_TRACE_ERROR("%s, no memory.", __func__);
|
||||
p += subevt_result.step_info[i].step_data_len;
|
||||
subevt_result.step_info[i].step_data_len = 0;
|
||||
subevt_result.step_info[i].data = NULL;
|
||||
subevt_result.num_steps_reported = i + 1;
|
||||
break;
|
||||
}
|
||||
remaining -= subevt_result.step_info[i].step_data_len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3521,7 +3669,7 @@ static void btu_ble_cs_subevt_result_evt(UINT8 *p)
|
||||
|
||||
}
|
||||
|
||||
static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p)
|
||||
static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p, UINT8 evt_len)
|
||||
{
|
||||
tBTM_BLE_CS_SUBEVT_RESULT_CONTINUE_EVT subevt_continue_result = {0};
|
||||
|
||||
@@ -3530,6 +3678,15 @@ static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fixed fields: conn_handle(2) + config_id(1) + proc_done_status(1)
|
||||
* + subevt_done_status(1) + abort_reason(1) + num_ant_paths(1)
|
||||
* + num_steps_reported(1) = 8 bytes
|
||||
* (subevent_code already subtracted from evt_len by caller) */
|
||||
if (evt_len < 8) {
|
||||
HCI_TRACE_ERROR("%s, evt too short (len=%u, need>=8)", __func__, evt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
STREAM_TO_UINT16(subevt_continue_result.conn_handle, p);
|
||||
STREAM_TO_UINT8(subevt_continue_result.config_id, p);
|
||||
STREAM_TO_UINT8(subevt_continue_result.proc_done_status, p);
|
||||
@@ -3539,26 +3696,47 @@ static void btu_ble_cs_subevt_result_continue_evt(UINT8 *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) {
|
||||
UINT8 remaining = evt_len - 8;
|
||||
subevt_continue_result.step_info = (subevt_continue_result.num_steps_reported > 0)
|
||||
? osi_malloc(subevt_continue_result.num_steps_reported * sizeof(tBTM_BLE_CS_STEP_INFO))
|
||||
: NULL;
|
||||
if (subevt_continue_result.step_info || subevt_continue_result.num_steps_reported == 0) {
|
||||
for (uint8_t i = 0; i < subevt_continue_result.num_steps_reported; i++) {
|
||||
if (remaining < 3) {
|
||||
HCI_TRACE_ERROR("%s, remaining %u too short for step %d", __func__, remaining, i);
|
||||
subevt_continue_result.num_steps_reported = i;
|
||||
break;
|
||||
}
|
||||
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
|
||||
remaining -= 3;
|
||||
if (subevt_continue_result.step_info[i].step_data_len > remaining) {
|
||||
HCI_TRACE_ERROR("%s, step_data_len %d exceeds remaining %u at step %d",
|
||||
__func__, subevt_continue_result.step_info[i].step_data_len, remaining, i);
|
||||
subevt_continue_result.step_info[i].step_data_len = 0;
|
||||
subevt_continue_result.step_info[i].data = NULL;
|
||||
subevt_continue_result.num_steps_reported = i + 1;
|
||||
break;
|
||||
}
|
||||
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);
|
||||
} else if (subevt_continue_result.step_info[i].step_data_len) {
|
||||
HCI_TRACE_ERROR("%s, no memory.", __func__);
|
||||
p += subevt_continue_result.step_info[i].step_data_len;
|
||||
subevt_continue_result.step_info[i].step_data_len = 0;
|
||||
subevt_continue_result.step_info[i].data = NULL;
|
||||
subevt_continue_result.num_steps_reported = i + 1;
|
||||
break;
|
||||
}
|
||||
remaining -= subevt_continue_result.step_info[i].step_data_len;
|
||||
}
|
||||
} else {
|
||||
HCI_TRACE_ERROR("%s, no memory for step_info.", __func__);
|
||||
|
||||
@@ -449,7 +449,17 @@ void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
|
||||
osi_mutex_lock(&btu_general_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (!hash_map_has_key(btu_general_alarm_hash_map, p_tle)) {
|
||||
alarm = osi_alarm_new("btu_gen", btu_general_alarm_cb, (void *)p_tle, 0);
|
||||
hash_map_set(btu_general_alarm_hash_map, p_tle, alarm);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_ERROR("%s Unable to create new alarm", __func__);
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
return;
|
||||
}
|
||||
if (!hash_map_set(btu_general_alarm_hash_map, p_tle, alarm)) {
|
||||
HCI_TRACE_ERROR("%s Unable to set alarm in map", __func__);
|
||||
osi_alarm_free(alarm);
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
|
||||
@@ -569,8 +579,12 @@ void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ti
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
hash_map_set(btu_l2cap_alarm_hash_map, p_tle, (void *)alarm);
|
||||
if (!hash_map_set(btu_l2cap_alarm_hash_map, p_tle, (void *)alarm)) {
|
||||
HCI_TRACE_ERROR("%s Unable to set alarm in map", __func__);
|
||||
osi_alarm_free(alarm);
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
|
||||
@@ -656,7 +670,17 @@ void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_
|
||||
osi_mutex_lock(&btu_oneshot_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (!hash_map_has_key(btu_oneshot_alarm_hash_map, p_tle)) {
|
||||
alarm = osi_alarm_new("btu_oneshot", btu_oneshot_alarm_cb, (void *)p_tle, 0);
|
||||
hash_map_set(btu_oneshot_alarm_hash_map, p_tle, alarm);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_ERROR("%s Unable to create new alarm", __func__);
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
return;
|
||||
}
|
||||
if (!hash_map_set(btu_oneshot_alarm_hash_map, p_tle, alarm)) {
|
||||
HCI_TRACE_ERROR("%s Unable to set alarm in map", __func__);
|
||||
osi_alarm_free(alarm);
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user