CVE-2025-0093 AI-generated analysis
platform/packages/modules/Bluetooth, btservice (bond state handling in BondStateMachine / AdapterService, MAP/PBAP/SIM access permissions)
When a device's bond state changes to BOND_NONE, the Bluetooth stack now resets that device's Message Access (MAP), Phonebook Access (PBAP) and SIM Access permissions to ACCESS_UNKNOWN, so access granted earlier does not survive unbonding.
Root cause
Nothing reset the per-device Message Access, Phonebook Access and SIM Access permissions (set through AdapterService.setMessageAccessPermission / setPhonebookAccessPermission / setSimAccessPermission) when a device's bond state changed to BOND_NONE. In android/app/src/com/android/bluetooth/btservice/BondStateMachine.java, the method that handles bond state changes and broadcasts ACTION_BOND_STATE_CHANGED (an in-file comment calls it sendIntent) updated the adapter properties and sent the intent, but left any earlier stored permission in place. So a device that was unbonded kept the MAP/PBAP/SIM access it had been granted before. This conflicts with the PBAP requirement, quoted in the commit message, that the user confirm at least the first connection from each new PCE, and with the MAP requirement that the MCE and MSE be bonded.
How the fix works
- android/app/src/com/android/bluetooth/btservice/BondStateMachine.java (the bond-state intent method; the in-file comment calls it sendIntent): a new block is added after the BONDED/pending-UUID handling and before the ACTION_BOND_STATE_CHANGED intent is built. It checks `if (newState == BluetoothDevice.BOND_NONE)` and calls mAdapterService.setMessageAccessPermission, setPhonebookAccessPermission and setSimAccessPermission with BluetoothDevice.ACCESS_UNKNOWN.
- The reset runs before mAdapterService.onBondStateChanged(device, newState) and before the broadcast.
- The block comes after the early `return` (line 472 at android-security-14.0.0_r29). That return is only reached when newState == BOND_BONDED with UUIDs still pending, so every BOND_NONE transition that reaches this method performs the reset.
- Android 15 (AdapterService.java): the same three setters are called, unqualified, when `toState == BOND_NONE`. They are placed after mDatabaseManager.handleBondStateChanged(device, fromState, toState), and a static import of BluetoothDevice.BOND_NONE is added. The Android 14 commit message says it is a backport of ag/30386015 that needed minor logic changes.
Completeness
- Covers all three profile access permissions (message, phonebook, SIM) for any device whose bond state becomes BOND_NONE through the patched path (BondStateMachine on Android 14, AdapterService bond-state handling on Android 15).
- Only acts on a BOND_NONE transition. The material does not show how permissions are handled for devices that were never bonded.
- Devices that were already unbonded before the update are not cleared retroactively. The material shows no migration or startup cleanup of existing permission entries.
- The fix depends on every BOND_NONE transition passing through the patched method. The material does not show whether other paths exist.
Behavior changes
- After unbonding, the stored message, phonebook and SIM access permissions for that device are set to ACCESS_UNKNOWN instead of keeping their earlier value.
- The three setter calls now run on every BOND_NONE transition, including for devices that never had a permission stored.
Per major
- Android 14: Adapted fix (commit 142acc56658c in android-security-14.0.0_r17): the reset is placed in the bond-state intent method of BondStateMachine.java and uses mAdapterService.set*AccessPermission. At android-security-14.0.0_r29, 3/3 patched lines are present. The commit message says it is a backport of ag/30386015 with minor logic changes.
- Android 15: Fixed (commit 090ca53cc13c in android-security-15.0.0_r5): the reset is placed in AdapterService.java after mDatabaseManager.handleBondStateChanged, plus a static import of BOND_NONE. At android-security-15.0.0_r17, 8/8 patched lines are present.
- Android 16: Not affected (not listed by the bulletin). The patched region (3/3 lines) is present at android-security-16.0.0_r8.
- Android 17: Not affected (not listed by the bulletin). The patched region (3/3 lines) is present at android-security-17.0.0_r1.
Unknowns
- The hunk headers do not show the exact method names in BondStateMachine.java and AdapterService.java. The in-file comment at lines 502-503 calls the BondStateMachine method sendIntent.
- The material does not show whether the access permissions are persisted to storage.
- The material does not show whether any bond-removal path bypasses the patched method.
- The material does not show the user-visible behaviour on the next MAP/PBAP/SIM connection after the reset (for example, whether the user is prompted again).
- Whether the Android 15 commit is the original change ag/30386015, and what that change contains, is not provided.