CVE-2026-0050 AI-generated analysis
platform/packages/modules/Bluetooth, btservice/AdapterService (bond state handling and per-device access permissions)
AdapterService.handleBondStateChanged now also revokes the stored per-device access permissions (message, phonebook and a third stored permission) when a device's bond state leaves BOND_BONDED (fromState == BOND_BONDED), not only when it reaches BOND_NONE. A device that reuses a bonded address and tries to rebond therefore loses the previously granted permissions, and the user is asked for consent again.
Root cause
In AdapterService.handleBondStateChanged, the stored device permissions (setMessageAccessPermission, setPhonebookAccessPermission and a third permission set in the same block) were reset to ACCESS_UNKNOWN only when toState == BOND_NONE. The commit message says that when a device with the same address as a previously bonded device tries to bond again, the adapter service may not receive a BOND_NONE state change. The new test models this as a direct BOND_BONDED to BOND_BONDING transition. As a result, the permissions granted to the original device stayed in place for the new, possibly different, device, and the user was not asked for consent again.
How the fix works
- android/app/src/com/android/bluetooth/btservice/AdapterService.java:handleBondStateChanged: the revocation condition is widened from `toState == BOND_NONE` to `toState == BOND_NONE || fromState == BOND_BONDED`. Any transition out of the BONDED state, including BONDED -> BONDING on a rebond attempt, now resets the stored access permissions to BluetoothDevice.ACCESS_UNKNOWN. A static import of BluetoothDevice.BOND_BONDED is added.
- On Android 17 (921aaec06df0) the new clause is behind a flag: `toState == BOND_NONE || (Flags.rebokePermissionOnUnbond() && fromState == BOND_BONDED)`. The Android 15 and 16 cherry-picks apply the clause without any flag check.
- android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java: the new test testRemovePermissionBondedToBonding mocks SharedPreferences and checks that handleBondStateChanged(device, BOND_BONDED, BOND_BONDING) causes three SharedPreferences.Editor.remove calls. On 17 the test carries @EnableFlags(Flags.FLAG_REBOKE_PERMISSION_ON_UNBOND).
Completeness
- Covers every transition whose fromState is BOND_BONDED, whatever the toState, in addition to the existing toState == BOND_NONE case. mDatabaseManager.handleBondStateChanged is still called before the permission block.
- Only the permission block in handleBondStateChanged changes. The diff does not touch other per-device state that may be keyed on the address (for example profile connection policies handled by mDatabaseManager), so this commit does not show whether that state also carries over on a rebond.
- The fix depends on the stack delivering a bond state change with fromState == BOND_BONDED for the rebond attempt. This change does not cover a path where no bond state callback is delivered at all.
- On Android 17 the new behavior depends on the runtime value of Flags.rebokePermissionOnUnbond(). With the flag off, the original condition still applies.
Behavior changes
- When a bonded device's bond state moves from BOND_BONDED to any other state (for example BOND_BONDING on a rebond), its message, phonebook and third stored access permissions are reset to ACCESS_UNKNOWN. Per the commit message, the user is then asked for consent again.
- On such transitions, three SharedPreferences entries for the device are removed, as the new unit test checks.
Per major
- Android 14: Not affected per the bulletin (not listed). At android-security-14.0.0_r29 only 4/8 lines of the patched region are present. No fix was applied there.
- Android 15: Same fix, applied as cherry-pick da365e87dce9 (from 921aaec06df0) in android-security-15.0.0_r16, Change-Id Id63a61908fb22c426c49d0979bba0c6a8b9dba03. The new clause has no flag check. 7/8 lines present at android-security-15.0.0_r17.
- Android 16: Same fix, applied as d0f7d128d436 in android-security-16.0.0_r7, also with no flag check. 7/8 lines present at android-security-16.0.0_r8.
- Android 17: Base fix 921aaec06df0 in android-17.0.0_r1. The new clause is gated by Flags.rebokePermissionOnUnbond(), and the test is annotated @EnableFlags(Flags.FLAG_REBOKE_PERMISSION_ON_UNBOND). 7/8 lines present at android-security-17.0.0_r1.
Unknowns
- Which permission is the third one reset in the block. The diff shows only setMessageAccessPermission and setPhonebookAccessPermission, while the test expects three SharedPreferences removes.
- Why the stack can skip the BOND_NONE transition on a rebond with the same address. The commit message only says it is possible, and the native/stack side is not in the material.
- Whether other per-device trust state outside this permission block also survives such a rebond.
- Where the reboke_permission_on_unbond flag is defined. The material does not include the aconfig definition.