diff --git a/system/stack/btm/btm_ble_batchscan.cc b/system/stack/btm/btm_ble_batchscan.cc index 22788809c5d0894f8be15923f29eb309b81ccc5d..bdce3676889b8fb538f67af07da306de4bbcf5d8 100644 --- a/system/stack/btm/btm_ble_batchscan.cc +++ b/system/stack/btm/btm_ble_batchscan.cc @@ -60,12 +60,15 @@ bool can_do_batch_scan() { /* VSE callback for batch scan, filter, and tracking events */ void btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len, const uint8_t* p) { - tBTM_BLE_TRACK_ADV_DATA adv_data; - + tBTM_BLE_TRACK_ADV_DATA adv_data{}; uint8_t sub_event = 0; tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - if (len == 0) return; + + if (len < 1) + goto err_out; + STREAM_TO_UINT8(sub_event, p); + len -= 1; BTM_TRACE_EVENT( "btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x", @@ -78,30 +81,45 @@ void btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len, if (HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT == sub_event && NULL != ble_advtrack_cb.p_track_cback) { - if (len < 10) return; - memset(&adv_data, 0, sizeof(tBTM_BLE_TRACK_ADV_DATA)); BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); adv_data.client_if = (uint8_t)ble_advtrack_cb.ref_value; if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) { + if (len < 10) { + goto err_out; + } + STREAM_TO_UINT8(adv_data.filt_index, p); STREAM_TO_UINT8(adv_data.advertiser_state, p); STREAM_TO_UINT8(adv_data.advertiser_info_present, p); STREAM_TO_BDADDR(adv_data.bd_addr, p); STREAM_TO_UINT8(adv_data.addr_type, p); + len -= 10; + /* Extract the adv info details */ if (ADV_INFO_PRESENT == adv_data.advertiser_info_present) { - if (len < 15) return; + + if (len < 5) { + goto err_out; + } + STREAM_TO_UINT8(adv_data.tx_power, p); STREAM_TO_UINT8(adv_data.rssi_value, p); STREAM_TO_UINT16(adv_data.time_stamp, p); - STREAM_TO_UINT8(adv_data.adv_pkt_len, p); + + len -= 5; + if (adv_data.adv_pkt_len > 0) { adv_data.p_adv_pkt_data = static_cast<uint8_t*>(osi_malloc(adv_data.adv_pkt_len)); + if (adv_data.p_adv_pkt_data == nullptr || \ + len < adv_data.adv_pkt_len) { + goto err_out; + } memcpy(adv_data.p_adv_pkt_data, p, adv_data.adv_pkt_len); + len -= adv_data.adv_pkt_len; p += adv_data.adv_pkt_len; } @@ -109,11 +127,19 @@ void btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len, if (adv_data.scan_rsp_len > 0) { adv_data.p_scan_rsp_data = static_cast<uint8_t*>(osi_malloc(adv_data.scan_rsp_len)); + + if (adv_data.p_scan_rsp_data == nullptr || len < adv_data.scan_rsp_len) { + goto err_out; + } memcpy(adv_data.p_scan_rsp_data, p, adv_data.scan_rsp_len); } } } else { /* Based on L-release version */ + if (len < 9) { + goto err_out; + } + STREAM_TO_UINT8(adv_data.filt_index, p); STREAM_TO_UINT8(adv_data.addr_type, p); STREAM_TO_BDADDR(adv_data.bd_addr, p); @@ -129,8 +155,15 @@ void btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len, to_ble_addr_type(adv_data.addr_type)); ble_advtrack_cb.p_track_cback(&adv_data); - return; } + + return; + +err_out: + BTM_TRACE_ERROR("malformatted packet detected"); + + osi_free_and_reset((void **) &adv_data.p_adv_pkt_data); + osi_free_and_reset((void **) &adv_data.p_scan_rsp_data); } void feat_enable_cb(uint8_t* p, uint16_t len) {