CVE-2024-0016 AI-generated analysis
platform/packages/modules/Bluetooth, system/stack BTM / BTU HCI event parsing (btm_ble_gap.cc, btu_hcif.cc)
Adds length validation to four HCI BLE event parsers in the Bluetooth stack (BIGInfo advertising report, LE advertising report, LE extended advertising report, LE data length change) so that fixed-size fields and per-report variable data are only read when the received packet actually contains them.
Root cause
Several HCI LE event handlers read fields with STREAM_TO_* macros without first checking the payload length. btm_ble_biginfo_adv_report_rcvd read 19 bytes of fixed fields with no check on param_len. btu_ble_data_length_change_evt read 8 bytes with no evt_len >= 8 check. btm_ble_process_adv_pkt and btm_ble_process_ext_adv_pkt read num_reports without checking data_len >= 1, and their per-report checks were pointer comparisons against data + data_len. The commit describes the result as missing bounds checks that could lead to out-of-bounds access.
How the fix works
- system/stack/btm/btm_ble_gap.cc:btm_ble_biginfo_adv_report_rcvd: adds `if (param_len < 19) { LOG_ERROR("Insufficient data"); return; }` before the STREAM_TO_* sequence. 19 is the sum of the fixed fields (sync_handle 2, num_bises 1, nse 1, iso_interval 2, bn/pto/irc 3, max_pdu 2, sdu_interval 3, max_sdu 2, phy/framing/encryption 3).
- system/stack/btm/btm_ble_gap.cc:btm_ble_process_ext_adv_pkt: adds a running `size_t bytes_to_process` counter. It checks data_len >= 1 before reading num_reports. For each report it adds 24 (the fixed report header) and checks data_len < bytes_to_process. After reading pkt_data_len it adds that length and checks again. These integer checks replace the old pointer comparisons (`p + extended_report_header_size > data + data_len`, `p > data + data_len`).
- system/stack/btm/btm_ble_gap.cc:btm_ble_process_adv_pkt: same scheme. It checks data_len >= 1 for num_reports. Per report it adds 9 header bytes (the old code used a 10-byte constant in a pointer check). After reading pkt_data_len it adds pkt_data_len + 1 so the trailing RSSI byte is covered. This replaces `p > data + data_len - sizeof(rssi)`.
- system/stack/btu/btu_hcif.cc:btu_ble_data_length_change_evt: adds `if (evt_len < 8) { LOG_ERROR("Event packet too short"); return; }` before reading handle, tx_data_len, TxTimer (skipped) and rx_data_len (2 bytes each).
Completeness
- Covers the four parsers in the diff. All fixed fields of the BIGInfo report and the data length change event are length-checked. Both advertising report parsers now validate the num_reports byte, each report header, the variable advertising data and, for legacy reports, the RSSI byte, using integer length counters.
- When a report is too short, the loop returns. Reports handled in earlier iterations of the same event have already been processed.
- This commit does not change the other HCI event handlers visible in the btu_hcif.cc context (btu_hcif_inquiry_comp_evt, btu_hcif_authentication_comp_evt, btu_hcif_rmt_name_request_comp_evt). btu_hcif_rmt_name_request_comp_evt subtracts 1 + BD_ADDR_LEN from evt_len with no length check visible in the function. The material does not show whether its callers check the length.
Behavior changes
- BIGInfo advertising reports shorter than 19 bytes and LE data length change events shorter than 8 bytes are now dropped with LOG_ERROR instead of being parsed.
- LE advertising and extended advertising report events with an empty payload, a short report header, or advertising data (plus RSSI for legacy reports) running past data_len are dropped with LOG(ERROR). The old BTM_TRACE_ERROR messages are replaced by LOG(ERROR) messages with new text.
Per major
- Android 14: same fix: commit b32ccd826436 in android-security-14.0.0_r4 (Change-Id If7752f6edd749d6d5a4bb957b4824c22b5602737, cherry-picked from internal commits 66e2be05 and 5d1a3feb). At android-security-14.0.0_r29, 8/8 lines of the patched region are present.
- Android 15: not affected per the bulletin. At android-security-15.0.0_r17 only 2/8 lines of the patched region are present. The material does not show how the equivalent parsing is handled there.
- Android 16: not affected per the bulletin. At android-security-16.0.0_r8 only 2/8 lines of the patched region are present. The material does not show how the equivalent parsing is handled there.
- Android 17: not affected per the bulletin. At android-security-17.0.0_r1 only 2/8 lines of the patched region are present. The material does not show how the equivalent parsing is handled there.
Unknowns
- The material does not show the HCI dispatch path on Android 14 that calls btm_ble_process_adv_pkt, btm_ble_process_ext_adv_pkt, btm_ble_biginfo_adv_report_rcvd or btu_ble_data_length_change_evt.
- The material does not show whether length validation happens upstream of these handlers (for example in the HCI layer).
- The material does not show what the existing early return in btu_ble_data_length_change_evt (before the new check) tests.
- The Android 13 fix commit is not included in the material.
- The material does not show how Android 15 and later handle the equivalent events. Most of the patched region is absent there.