CVE-2025-0082 AI-generated analysis
platform/frameworks/base (telecomm/java/android/telecom/StatusHints.java) and platform/packages/services/Telecomm (TelecomServiceImpl), Telecom icon URI validation
Replaces the Uri.getEncodedUserInfo()-based cross-user icon check in telecom StatusHints and TelecomServiceImpl (phone account registration) with a new StatusHints.getUserIdFromAuthority() helper that derives the user id from the URI authority (getAuthority()) and rejects any mismatch or unparsable user id.
Root cause
Both StatusHints (icon validation returning the icon or null) and TelecomServiceImpl (icon validation when registering a phone account) decided whether a TYPE_URI / TYPE_URI_ADAPTIVE_BITMAP icon belonged to the calling user by calling icon.getUri().getEncodedUserInfo(). If that returned null the code assumed the URI targeted the calling user's space and accepted it. Per the commit message and the new tests, an authority written with a percent-encoded separator (e.g. encodedAuthority "10%40media" or "content://10%40play.ground") is not parsed properly by that accessor, so the user id embedded in the authority was not compared against the caller and an icon URI naming another user passed validation. The old code also called Integer.parseInt on the user-info without catching NumberFormatException.
How the fix works
- platform/frameworks/base 24e31767630f, telecomm/java/android/telecom/StatusHints.java: adds a public static @hide helper getUserIdFromAuthority(String auth, int defaultUserId). It returns defaultUserId when auth is null or contains no '@'; otherwise it takes the substring before the last '@' and Integer.parseInt()s it; on NumberFormatException it logs a warning and returns UserHandle.USER_NULL. It is called on icon.getUri().getAuthority() rather than the encoded user-info.
- Same commit, StatusHints.java icon validation (the method that returns the icon or null, around line 150): for TYPE_URI / TYPE_URI_ADAPTIVE_BITMAP icons it now computes callingUserId = callingUserHandle.getIdentifier(), requestingUserId = getUserIdFromAuthority(icon.getUri().getAuthority(), callingUserId), and returns null (drops the icon) when they differ. Unparsable user ids map to USER_NULL and are therefore rejected rather than throwing.
- platform/packages/services/Telecomm e1a0858925cb, src/com/android/server/telecom/TelecomServiceImpl.java (icon check in phone account registration, around line 3150): imports android.telecom.StatusHints, replaces the getEncodedUserInfo() logic with callingUserId = UserHandle.getCallingUserId() and requestingUserId = StatusHints.getUserIdFromAuthority(icon.getUri().getAuthority(), callingUserId), and throws IllegalArgumentException("Attempting to register a phone account with an image icon belonging to another user.") when they differ.
- Same Telecomm commit, tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java testRegisterPhoneAccountImageIconCrossUser: adds two negative cases using encodedAuthority("10%40media") and Uri.parse("content://10%40play.ground") that must fail registration, keeping the existing positive case content://0@media/... that must succeed.
Completeness
- Covers both sites named in the commit message: the StatusHints icon validation and the TelecomServiceImpl phone-account registration icon check; both now share one parser so behavior is consistent.
- The check still applies only to icons of type Icon.TYPE_URI or Icon.TYPE_URI_ADAPTIVE_BITMAP; other icon types are untouched.
- The parser uses lastIndexOf('@') on the authority, so everything before the last '@' is parsed; a non-numeric prefix yields USER_NULL and is rejected.
- A URI with no '@' in the authority is treated as belonging to the caller (defaultUserId), which matches the previous code's stated intent; whether any other code path accepts caller-supplied icon URIs without going through these two checks is not shown in the material.
Behavior changes
- Phone account registration with a URI icon whose authority carries a different user id (including percent-encoded forms such as 10%40media) now throws IllegalArgumentException instead of being accepted.
- StatusHints drops (returns null for) a URI icon whose authority names another user, now also for percent-encoded forms.
- A URI icon whose user-id prefix is not an integer no longer causes an uncaught NumberFormatException; it is logged (TAG StatusHints) and treated as a user mismatch (rejected).
- TelecomServiceImpl now obtains the caller via UserHandle.getCallingUserId() instead of UserHandle.getUserId(Binder.getCallingUid()).
Per major
- Android 14: same fix: resolved via bug_id in android-security-14.0.0_r18 with both commits (frameworks/base 24e31767630f, Telecomm e1a0858925cb); at android-security-14.0.0_r29 the patched region is fully present (8/8 lines) and StatusHints.java contains the new TAG/Log import.
- Android 15: same fix: resolved in android-security-15.0.0_r6 via Telecomm 685c2fc2f6b4, whose diff matches the 14 one apart from line offsets (hunk at TelecomServiceImpl line ~3421, test at ~1090); 8/8 lines present at android-security-15.0.0_r17. The corresponding frameworks/base commit for 15 is not shown in the material, though the Telecomm code depends on StatusHints.getUserIdFromAuthority.
- Android 16: not affected per the bulletin (not listed); the patched region is fully present (8/8 lines) at android-security-16.0.0_r8.
- Android 17: not affected per the bulletin; at android-security-17.0.0_r1 the patched file telecomm/java/android/telecom/StatusHints.java is absent at that path; the material does not show where (or whether) the code lives now.
Unknowns
- The exact names of the two patched validation methods (the diff hunks do not include the method signatures).
- Whether the frameworks/base StatusHints commit was also applied to the Android 15 and 16 security branches (only the Telecomm commit is listed for 15; 16 shows the patched region present).
- Where the StatusHints code lives in Android 17 after the file disappeared from telecomm/java/android/telecom/.
- What permission, if any, gates the registerPhoneAccount icon path for third-party callers (the test grants MODIFY_PHONE_STATE but the production check is not shown).
- What device user/profile configuration is needed for a foreign-user icon URI to resolve to content.
- What exactly was disclosed (the bulletin only rates it High / ID).