CVE-2026-28634 AI-generated analysis
platform/packages/services/Telephony, PhoneInterfaceManager (ITelephony binder service, USSD handling)
Adds a check to PhoneInterfaceManager.handleUssdRequest that the calling user is associated with the subscription. A caller that passes enforceCallPermission can no longer send USSD requests on a subscription that is not associated with its user.
Root cause
PhoneInterfaceManager.handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) called only enforceCallPermission() (and, on 15+, enforceTelephonyFeatureWithException). It then cleared the calling identity and dispatched CMD_HANDLE_USSD_REQUEST for the subId the caller supplied. Nothing verified that the Binder calling user was associated with that subscription.
How the fix works
- src/com/android/phone/PhoneInterfaceManager.java:handleUssdRequest: after the existing permission checks and before Binder.clearCallingIdentity(), the method now calls TelephonyPermissions.checkSubscriptionAssociatedWithUser(mApp, subId, Binder.getCallingUserHandle()). If that returns false, it throws SecurityException("The subscription <subId> is not associated with the calling user").
- The check runs while the caller's identity is still in effect, so Binder.getCallingUserHandle() reflects the real caller rather than the phone process.
- tests/src/com/android/phone/PhoneInterfaceManagerTest.java adds two tests. testHandleUssdRequest_SubscriptionNotAssociatedWithUser_ThrowsSecurityException mocks SubscriptionManagerService.isSubscriptionAssociatedWithUser to return false and asserts a SecurityException. testHandleUssdRequest_ValidSubscription_Success mocks it to return true and accepts the main-thread deadlock RuntimeException as proof that the check passed. setUp now installs the mocked SubscriptionManagerService as sInstance and stubs getActiveSubIdList.
Completeness
- The fix covers only the handleUssdRequest entry point. The single new check gates the whole method before sendRequest(CMD_HANDLE_USSD_REQUEST).
- The sibling MMI path handlePinMmiForSubscriber(int subId, String dialString) appears directly below in the same file. It still calls enforceModifyPermission(), then clearCallingIdentity() and sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId), with no user-association check. The fix does not touch it.
- The new check runs before SubscriptionManager.isValidSubscriptionId(subId). The outcome for invalid subIds therefore depends on TelephonyPermissions.checkSubscriptionAssociatedWithUser, and its implementation is not in the material.
Behavior changes
- handleUssdRequest now throws SecurityException to the binder caller when the calling user is not associated with the given subscription. Before the fix, the request was dispatched.
- Exception message: "The subscription <subId> is not associated with the calling user".
- Callers that relied on an invalid subId returning silently may now get a SecurityException first, depending on how checkSubscriptionAssociatedWithUser handles invalid ids.
Per major
- Android 14: Same fix (2a177c06ec48, android-security-14.0.0_r29). The check is inserted directly after enforceCallPermission(); handleUssdRequest on this security tag has no enforceTelephonyFeatureWithException call. 8/8 lines of the patched region present.
- Android 15: Same fix (83d27ac3f32f, android-security-15.0.0_r17). The same 5-line check is inserted after enforceTelephonyFeatureWithException(...). Test setUp also stubs HalVersion, Phone.getContext, DataNetworkController and getDefaultPhone. 8/8 lines present.
- Android 16: Same fix (03cc6ee76027, android-security-16.0.0_r8). The same check is inserted after enforceTelephonyFeatureWithException. The test file drops its local Phone mock and adds imports. 8/8 lines present.
- Android 17: Same fix (5ef227b0a2f7, android-security-17.0.0_r1). The same check is inserted after enforceTelephonyFeatureWithException. The test file reorganises its mock fields. 8/8 lines present.
Unknowns
- The material does not show how TelephonyPermissions.checkSubscriptionAssociatedWithUser is implemented (for example, how it treats invalid subIds, system or root callers, or single-user devices), or which project defines it.
- The two Cherrypick-From changes (b76670f3c5ba, 0dfb804981a7) are internal. Whether they differ from the public commit is unknown.
- The bulletin rates this High/EoP, but the material does not describe the concrete impact of sending USSD on another user's subscription.