CVE-2026-0054 AI-generated analysis
platform/frameworks/base, SystemUI wallet (packages/SystemUI/src/com/android/systemui/wallet/controller/WalletContextualLocationsService.kt)
Adds an onTransact-level caller check to SystemUI's WalletContextualLocationsService binder so that only privileged apps holding the android.app.role.SYSTEM_UI_INTELLIGENCE role can invoke IWalletContextualLocationsService methods; all other callers get a SecurityException.
Root cause
The IWalletContextualLocationsService.Stub returned by WalletContextualLocationsService did not validate its caller. Its two AIDL methods were forwarded directly to the internal implementations for any process that could bind to the service: addWalletCardsUpdatedListener (to addWalletCardsUpdatedListenerInternal) and onWalletContextualLocationsStateUpdated (to onWalletContextualLocationsStateUpdatedInternal, which the context shows feeding store locations into controller.setSuggestionCardIds). The class comment says the service was designed as an intermediary between QuickAccessWalletService and ContextualCardManager in PCC, but nothing in the code limited it to that intended caller. The bulletin classifies the issue as information disclosure (ID), High.
How the fix works
- WalletContextualLocationsService.kt: the anonymous IWalletContextualLocationsService.Stub now overrides onTransact(code, data, reply, flags). Before delegating to super.onTransact, it calls isCallerAllowed() and throws SecurityException("Caller is not allowed.") if that returns false. Because the check is in onTransact, it gates every transaction on the stub, not individual methods.
- WalletContextualLocationsService.kt: the new private isCallerAllowed() reads Binder.getCallingUid() and clears the calling identity (Binder.clearCallingIdentity, restored in finally). It resolves packageManager.getPackagesForUid(uid) and returns false if the result is null or empty. It then fetches RoleManager.getRoleHolders("android.app.role.SYSTEM_UI_INTELLIGENCE"), using an empty list if RoleManager is unavailable. It returns true only if at least one of the caller's packages is in the role holder list AND packageManager.getApplicationInfo(packageName, 0).isPrivilegedApp() is true. A NameNotFoundException counts as false.
- WalletContextualLocationsService.kt companion object: adds the ROLE_SYSTEM_UI_INTELLIGENCE constant. The commit message calls this a quick fix, chosen to match the originally intended caller and the existing primary callers, and says a dedicated permission should replace it later.
Completeness
- Covers both existing AIDL methods (addWalletCardsUpdatedListener, onWalletContextualLocationsStateUpdated) and any future methods on the stub, because the check sits in onTransact.
- Authorization is based on the role and on privileged status, not on a manifest permission; the commit itself says a new permission should replace it. The check accepts the call if ANY package sharing the calling UID holds the role and is privileged, not necessarily the package that made the call.
- The diff does not change binding to the service (onBind); only transactions are rejected. The material does not show whether the service is exported in the SystemUI manifest.
- The fix does not change the listener callback side (IWalletCardsUpdatedListener) or WalletContextualSuggestionsController; it relies only on gating entry to the service.
Behavior changes
- Any binder transaction to WalletContextualLocationsService from a caller that is not a privileged app holding SYSTEM_UI_INTELLIGENCE now fails with SecurityException ("Caller is not allowed.").
- Each transaction now performs PackageManager and RoleManager lookups under a cleared calling identity before dispatch.
- On Android 14 the diff also reformats the binder stub declaration (no functional change).
Per major
- Android 14: Same fix: platform/frameworks/base a83edee34b0d in android-security-14.0.0_r28 (Change-Id I7e8b2bf83727464369b94c63e208c5717601a51f). The diff also reformats the stub declaration because the 14 branch used the older layout. 8/8 lines of the patched region are present at android-security-14.0.0_r29.
- Android 15: Same fix: 3717e022bc2a in android-security-15.0.0_r16, with identical logic, applied on the already reformatted stub at different line offsets. 8/8 lines are present at android-security-15.0.0_r17.
- Android 16: Same fix: a8f3c0ccb472 in android-security-16.0.0_r7, with identical logic; the context differs only by the existing android.os.DeadObjectException import. 8/8 lines are present at android-security-16.0.0_r8.
- Android 17: Not affected (the bulletin does not list Android 17). The patched region (8/8 lines) is present at android-security-17.0.0_r1.
Unknowns
- Manifest attributes of WalletContextualLocationsService (exported state, any permission attribute), and therefore which processes could bind before the fix.
- What data the registered IWalletCardsUpdatedListener receives, and what exact disclosure the bulletin rates as High.
- Contents of the companion STS test commit I4c59ae71f66035d2aeeb9b9e4dd13d7911e5fae5.