CVE-2025-48628 AI-generated analysis
platform/frameworks/base, print service (services/print, PrintManagerService)
PrintManagerService.validateIconUserBoundary now derives the icon URI's user id from the URI authority via ContentProvider.getUserIdFromAuthority (defaulting to the resolved calling user) and always enforces the current-user-group check for URI-type icons, instead of relying on Uri.getEncodedUserInfo and skipping the check when it returned null.
Root cause
In services/print/java/com/android/server/print/PrintManagerService.java, validateIconUserBoundary(Icon) got the user id of a TYPE_URI / TYPE_URI_ADAPTIVE_BITMAP icon from icon.getUri().getEncodedUserInfo(). The commit message says a specially crafted URI could make Uri.getEncodedUserInfo return an incorrect value. The old code ran the "current group members only" check (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) only when encodedUser was non-null. When it was null, the method skipped the check and assumed the URI pointed into the caller's own user space. The old code also called Integer.parseInt(encodedUser) directly and resolved the parsed user via resolveCallingUserEnforcingPermissions.
How the fix works
- PrintManagerService.java: the binder method that obtains the icon via userState.getCustomPrinterIcon(printerId) now passes its resolved calling user (resolvedUserId) to validateIconUserBoundary(icon, resolvedUserId).
- PrintManagerService.java: validateIconUserBoundary(Icon, int resolvedCallingId) replaces getEncodedUserInfo + Integer.parseInt + resolveCallingUserEnforcingPermissions with ContentProvider.getUserIdFromAuthority(icon.getUri().getAuthority(), resolvedCallingId). The user id now comes from the authority component, with resolvedCallingId passed as the default.
- PrintManagerService.java: the synchronized(mLock) check resolveCallingProfileParentLocked(iconUserId) != getCurrentUserId() -> return null now runs unconditionally for URI-type icons; it is no longer nested under 'if (encodedUser != null)'.
- Adds import android.content.ContentProvider.
Completeness
- Covers the call path shown in the diff (userState.getCustomPrinterIcon -> validateIconUserBoundary) for icons of type Icon.TYPE_URI and Icon.TYPE_URI_ADAPTIVE_BITMAP.
- Per the unchanged type condition, icons of other types are not subject to this check; the diff does not change that.
- The fix changes how the user id is extracted; it adds no further validation of other URI components. Whether other print service paths return Icons or URIs to callers is not shown in the material.
Behavior changes
- URI-type custom printer icons whose authority carries no user prefix are now checked against the resolved calling user instead of being returned without any check.
- User id extraction moved from Uri.getEncodedUserInfo to ContentProvider.getUserIdFromAuthority; the explicit Integer.parseInt on the user-info string is removed from this method.
- resolveCallingUserEnforcingPermissions is no longer invoked on the user id embedded in the icon URI; the caller's resolved user is passed in as the default instead.
- For URI-type icons, the method returns null (icon withheld) whenever the icon's user id does not resolve to the current user's profile group.
Per major
- Android 14: same fix: commit 0d6bfc8a1f50 in android-security-14.0.0_r24 (cherry-pick of 8d40513846ee); 8/8 patched lines present at android-security-14.0.0_r29.
- Android 15: same fix: commit 3723e843b659 in android-security-15.0.0_r12, identical diff; 8/8 lines present at android-security-15.0.0_r17.
- Android 16: same fix: commit 9489a5dcd3cd in android-security-16.0.0_r3, identical diff; 8/8 lines present at android-security-16.0.0_r8.
- Android 17: not affected (not listed by the bulletin); patched region present 8/8 at android-security-17.0.0_r1.
Unknowns
- The exact URI construction that makes Uri.getEncodedUserInfo return an incorrect value is not shown (commit message only).
- What data a leaked cross-user icon URI could expose is not shown; the bulletin classifies it as ID (information disclosure), High.
- Whether an Android 13 fix commit exists is not in the material.
- The name of the enclosing binder method and the implementations of Icon#getUriString and userState.getCustomPrinterIcon (how the icon URI is sourced) are not in the material.