CVE-2026-28574 AI-generated analysis
platform/packages/modules/Nfc, NfcNci card emulation (HostEmulationManager)
In HostEmulationManager.HostEmulationServiceConnection.onServiceConnected, when the HCE state is already STATE_IDLE and the connected service is not the preferred service, the fix now unbinds the service connection and removes its entry from mComponentNameToConnectionsMap. Before the fix, the code returned and left the binding alive.
Root cause
HostEmulationManager binds to a host card emulation service. If mState had already gone back to STATE_IDLE by the time onServiceConnected ran, and the component was no longer the preferred service, the code took an early return ("Service is already deactivated and not preferred, don't bind"). That early return neither called unbindService nor cleared the tracking entry in mComponentNameToConnectionsMap, so the binding the NFC service started stayed in place. The commit title says this left a permanent background activity launch (BAL) grant tied to the binding, which matches the EoP type in the bulletin.
How the fix works
- NfcNci/src/com/android/nfc/cardemulation/HostEmulationManager.java:HostEmulationServiceConnection.onServiceConnected: inside the existing `mState == STATE_IDLE && !name.equals(preferredServiceName)` branch (held under mLock), the fix calls mContext.unbindService(this) before returning. It catches IllegalArgumentException and logs the warning 'Failed to unbind <name>'.
- Same branch: the fix also removes the ComponentNameAndUser(mUserId, name) key from mComponentNameToConnectionsMap.
- Single commit, 7 lines added. No other paths or files are touched.
Completeness
- The fix covers only the early-return path in onServiceConnected where the state is idle and the service is not preferred. The normal path (state not idle, or service is preferred) still stores the Messenger and keeps the binding as before.
- The map removal is unconditional. When isMultipleBindingSupported() is false, the connection is tracked through mService/mServiceName/mServiceBound rather than the map. This branch does not touch those fields, which is consistent because they are never set on this path.
- An unbindService failure is only logged and not retried. If unbinding throws, the map entry is still removed.
Behavior changes
- A host emulation service that connects after the state has already returned to idle, and that is not the preferred service, is now unbound immediately instead of staying bound.
- New warning log 'Failed to unbind <name>' if unbindService throws IllegalArgumentException.
- The connection entry for that component/user is removed from mComponentNameToConnectionsMap.
Per major
- Android 14: Not affected per the bulletin. The project packages/modules/Nfc is not present in android-security-14.0.0_r29 (code absent).
- Android 15: Not affected per the bulletin. The project is not present in android-security-15.0.0_r17 (code absent).
- Android 16: Same fix: commit 477d0eb9f0f6 in android-security-16.0.0_r7 (cherry-pick of 6564c573280aad995b6e71536a1b8c190c63afea). 4/4 patched lines are present at android-security-16.0.0_r8.
- Android 17: Listed as affected (17-next), but marked platform-only, with no resolved commit in the material. At android-security-17.0.0_r1 only 3/4 lines of the patched region are present, so the fix status there is unconfirmed.
Unknowns
- How the leaked binding turns into a background activity launch grant is stated only in the commit title. The diff does not show it.
- Whether Android 17 (android-security-17.0.0_r1, 3/4 lines present) contains an equivalent fix or a differently formatted version of it.
- The provided context does not show which caller or sequence races the deactivation against onServiceConnected.
- Whether the fix also reaches devices through a module update separate from the platform security tag.