CVE-2023-40080 AI-generated analysis
platform/packages/modules/Bluetooth, BT stack BLE GAP periodic advertising sync (system/stack/btm/btm_ble_gap.cc)
Adds MAX_SYNC_TRANSACTION checks on the index returned by the periodic-sync table lookups in system/stack/btm/btm_ble_gap.cc before it is used to address btm_ble_pa_sync_cb.p_sync[] and btm_ble_pa_sync_cb.sync_transfer[], across five functions.
Root cause
The added checks show that btm_ble_get_psync_index(sid, addr) and btm_ble_get_free_sync_transfer_index() can return MAX_SYNC_TRANSACTION as a 'not found / no free slot' value. In btm_ble_start_sync_request and btm_ble_start_sync_timeout, the result of btm_ble_get_psync_index was used directly to form &btm_ble_pa_sync_cb.p_sync[index] without checking for that value; btm_ble_start_sync_request then wrote p->sync_state. In BTM_BlePeriodicSyncTransfer and BTM_BlePeriodicSyncSetInfo, the result of btm_ble_get_free_sync_transfer_index was used directly as &btm_ble_pa_sync_cb.sync_transfer[index] and written (p_sync_transfer->in_use = true) without a check. In BTM_BleStartPeriodicSync the sentinel was already checked, but the pointer &p_sync[index] was computed before the check. The commit title describes these as OOB bugs.
How the fix works
- system/stack/btm/btm_ble_gap.cc:btm_ble_start_sync_request: after int index = btm_ble_get_psync_index(sid, addr), if index == MAX_SYNC_TRANSACTION, LOG_ERROR and return before computing p = &btm_ble_pa_sync_cb.p_sync[index] and setting p->sync_state.
- system/stack/btm/btm_ble_gap.cc:btm_ble_start_sync_timeout: the same check after btm_ble_get_psync_index(adv_sid, address); LOG_ERROR and return before p is taken from p_sync[index].
- system/stack/btm/btm_ble_gap.cc:BTM_BleStartPeriodicSync: the existing index == MAX_SYNC_TRANSACTION check (syncCb with BTM_NO_RESOURCES, then return) is kept, and the computation of p = &btm_ble_pa_sync_cb.p_sync[index] is moved after it.
- system/stack/btm/btm_ble_gap.cc:BTM_BlePeriodicSyncTransfer: after int index = btm_ble_get_free_sync_transfer_index(), if index == MAX_SYNC_TRANSACTION, BTM_TRACE_ERROR, cb.Run(BTM_ILLEGAL_VALUE, addr) and return before writing sync_transfer[index].
- system/stack/btm/btm_ble_gap.cc:BTM_BlePeriodicSyncSetInfo: the same check, with an early return through cb.Run(BTM_ILLEGAL_VALUE, addr), before writing sync_transfer[index].
Completeness
- The fix guards all five index uses in the diff: two users of btm_ble_get_psync_index (btm_ble_start_sync_request, btm_ble_start_sync_timeout), a reordering in BTM_BleStartPeriodicSync, and two users of btm_ble_get_free_sync_transfer_index (BTM_BlePeriodicSyncTransfer, BTM_BlePeriodicSyncSetInfo).
- The check compares only against the exact value MAX_SYNC_TRANSACTION, so it relies on the helpers never returning any other out-of-range value.
- Other users of these index helpers elsewhere in btm_ble_gap.cc are not in the material, so it is not shown whether they already check the sentinel.
- The fix is a single commit to one file, with no helper or header changes.
Behavior changes
- BTM_BlePeriodicSyncTransfer and BTM_BlePeriodicSyncSetInfo now call the caller's callback with BTM_ILLEGAL_VALUE and return when no free sync_transfer slot index is returned.
- btm_ble_start_sync_request now returns early with a LOG_ERROR when the lookup returns MAX_SYNC_TRANSACTION; in that case PeriodicScanStart is not issued and the SYNC_TIMEOUT alarm is not armed.
- btm_ble_start_sync_timeout now returns early with a LOG_ERROR when the lookup returns MAX_SYNC_TRANSACTION, skipping the rest of the timeout handling.
- BTM_BleStartPeriodicSync behaviour is unchanged (same BTM_NO_RESOURCES callback); only the pointer computation moved.
Per major
- Android 14: same fix: commit 397c1e928552 in android-security-14.0.0_r3 (cherry-pick of internal 3bb913ee8c7d); all 8 patched lines present at android-security-14.0.0_r29.
- Android 15: not affected per the bulletin (not listed); the patched region (8/8 lines) is present at android-security-15.0.0_r17.
- Android 16: not affected per the bulletin (not listed); the patched region (8/8 lines) is present at android-security-16.0.0_r8.
- Android 17: not affected per the bulletin (not listed); 0/8 patched lines present at android-security-17.0.0_r1. The material does not show why.
Unknowns
- The definitions of btm_ble_get_psync_index, btm_ble_get_free_sync_transfer_index, MAX_SYNC_TRANSACTION and the btm_ble_pa_sync_cb arrays (including their sizes) are not in the material; the sentinel meaning is inferred from the added checks.
- Whether other users of these index helpers in btm_ble_gap.cc already check the sentinel.
- Who calls these functions and how far up the trigger reaches.
- Which of the two bugs (275057843, 275057678) maps to which function, and the exact trigger used in testing.
- Why the patched lines are absent at android-security-17.0.0_r1.