CVE-2026-28623 AI-generated analysis
platform/packages/modules/Uwb, ranging framework (android.ranging.ble.cs / android.ranging.ble.rssi Parcelables)
Stops the device Bluetooth MAC address from being serialized in BleCsRangingCapabilities and BleRssiRangingCapabilities parcels. The Parcel constructors now always produce the placeholder "00:00:00:00:00:00", while the builder/constructor path used inside the ranging service keeps the real address.
Root cause
BleCsRangingCapabilities.writeToParcel wrote mBluetoothAddress with dest.writeString, and the private Parcel constructor read it back with in.readString. BleRssiRangingCapabilities did the same. These objects are transacted over binder, so an app receiving them could read the device's real Bluetooth address through getBluetoothAddress(). The commit message describes this as a mac address leak to user apps.
How the fix works
- ranging/framework/java/android/ranging/ble/cs/BleCsRangingCapabilities.java: adds DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00". writeToParcel no longer writes mBluetoothAddress; only the supported security levels list is written. The Parcel constructor BleCsRangingCapabilities(Parcel in) sets mBluetoothAddress = DEFAULT_MAC_ADDRESS instead of calling in.readString(). The Builder-based constructor is unchanged, so the service-side object still holds the real address.
- ranging/framework/java/android/ranging/ble/rssi/BleRssiRangingCapabilities.java: adds the same DEFAULT_MAC_ADDRESS constant. writeToParcel now has an empty body, and the protected Parcel constructor sets mBluetoothAddress = DEFAULT_MAC_ADDRESS. getBluetoothAddress() gains @NonNull and a javadoc saying it is for internal use and that clients should use BluetoothAdapter#getAddress(). The String constructor is unchanged for internal use.
- ranging/framework/tests/src/android/ranging/RangingFrameworkTest.java: adds testBleCsRangingCapabilitiesParcel and testBleRssiRangingCapabilitiesParcel. Each asserts the real address before parceling and the fake address after CREATOR.createFromParcel.
Completeness
- Both classes named in the commit (CS and RSSI capabilities) are fixed. The write and read sides change consistently, so the parcel layout stays self-consistent.
- The address is masked only at the parcel boundary. In-process objects built by the service still carry the real address, which the commit message says is intentional. The material does not show any other service-to-app channel that might carry the address, and this commit does not touch one.
Behavior changes
- Apps that unparcel BleCsRangingCapabilities or BleRssiRangingCapabilities now always get "00:00:00:00:00:00" from getBluetoothAddress().
- The parcel wire format changed: neither class writes or reads the trailing address string any more, and BleRssiRangingCapabilities.writeToParcel now writes nothing.
- getBluetoothAddress() on BleRssiRangingCapabilities is now annotated @NonNull and documented as internal-only.
Per major
- Android 14: Not affected per the bulletin. The patched files are absent at android-security-14.0.0_r29 (code absent).
- Android 15: Not affected per the bulletin. The patched files are absent at android-security-15.0.0_r17 (code absent).
- Android 16: Same fix: commit 4a9740318035 in android-security-16.0.0_r8 (cherry-pick of c8aed37c3cd8), resolved by bug_id. 7 of 8 lines of the patched region are present.
- Android 17: Same fix: commit 5dbf65f08b16 in android-security-17.0.0_r1, resolved by bug_id. The source-file diff is identical; only the test file base and hunk offsets differ. 7 of 8 lines of the patched region are present.
Unknowns
- Which ranging service binder calls return these capability objects, and what caller permissions apply.
- Whether the Bluetooth address reaches apps through any other path in the ranging stack.
- Whether BleRssiRangingCapabilities.toString() includes mBluetoothAddress (the diff context cuts off).
- Why the resolver reports 7 of 8 lines of the patched region present on 16 and 17.
- Whether the patch applies cleanly to customized fork trees.