CVE-2025-48582 AI-generated analysis
platform/packages/providers/MediaProvider, PermissionActivity / bulk request PendingIntent creation (MediaProvider.java)
MediaProvider now records the uid of the app that created a bulk create request inside the PendingIntent extras for PermissionActivity, and PermissionActivity uses that uid, instead of Activity.getCallingPackage(), to decide whether user consent is needed and to which package URI permissions are granted.
Root cause
MediaProvider builds a PendingIntent targeting PermissionActivity for create bulk requests (e.g. CREATE_WRITE_REQUEST_CALL) but did not record which uid created the request. PermissionActivity.resolveCallingAppInfo() relied solely on getCallingPackage(), i.e. the package that started the activity, and that package name was also passed to shouldShowActionDialog() (consent decision), to grantUriPermission() (recipient of READ/WRITE URI grants) and to Metrics. The identity used for the permission check and the grant could therefore differ from the identity that created the request. The app info was also resolved with getApplicationInfo() rather than for the caller's user.
How the fix works
- apex/framework/java/android/provider/MediaStore.java: adds hidden constant EXTRA_CALLING_PACKAGE_UID = "calling_package_uid" (Android 14 commit; the 15/16 diffs shown do not include MediaStore.java).
- src/com/android/providers/media/MediaProvider.java (PendingIntent builder for PermissionActivity, hunk around line 6971 on 14 / 7645 on 15 / 8384 on 16): before intent.putExtras(extras), adds extras.putInt(EXTRA_CALLING_PACKAGE_UID, getCallingUidOrSelf()). On 14 the PendingIntent is created with FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE.
- src/com/android/providers/media/PermissionActivity.java:resolveCallingAppInfo(): if the intent has extras, reads EXTRA_CALLING_PACKAGE_UID, resolves the package via Objects.requireNonNull(getPackageManager().getPackagesForUid(callingUid))[0], derives the UserHandle with UserHandle.getUserHandleForUid(callingUid), and resolves the app with getApplicationInfoAsUser(callingPackage, 0, userHandle). getCallingPackage()/getUser() remain only as the fallback when extras == null.
- src/com/android/providers/media/PermissionActivity.java (consent-decision code): both shouldShowActionDialog(...) invocations now receive appInfo.packageName instead of getCallingPackage().
- src/com/android/providers/media/PermissionActivity.java: the positive-action AsyncTask now calls grantUriPermission(appInfo.packageName, uri, READ|WRITE) for CREATE_WRITE_REQUEST_CALL, and Metrics.logPermissionGranted / logPermissionDenied use appInfo.packageName.
Completeness
- All uses of getCallingPackage() for authorization and grants in PermissionActivity shown in the diff are replaced; only the fallback inside resolveCallingAppInfo() (extras == null) still uses it.
- When extras is non-null but lacks EXTRA_CALLING_PACKAGE_UID, extras.getInt() returns 0 and getPackagesForUid(0) is used; the resulting behavior is not shown in the material.
- For shared-uid packages the fix takes getPackagesForUid(uid)[0]; the consent check and grantUriPermission are performed against the first package of the uid group rather than necessarily the specific requesting package.
- The grant branch patched is CREATE_WRITE_REQUEST_CALL; other branches of the switch are not shown in the diff.
Behavior changes
- Bulk request PendingIntents now carry an extra int 'calling_package_uid'.
- PermissionActivity resolves the requesting app via its uid and user (getApplicationInfoAsUser), so callers are resolved in their own user.
- If the stored uid cannot be mapped to a package (getPackagesForUid returns null), resolveCallingAppInfo throws NullPointerException (Objects.requireNonNull) instead of NameNotFoundException.
- Metrics now attribute grant/deny events to the resolved request creator's package.
Per major
- Android 14: same fix: commit 45db544a1f1a in android-security-14.0.0_r25, touching MediaStore.java (adds EXTRA_CALLING_PACKAGE_UID), MediaProvider.java and PermissionActivity.java; 8/8 patched lines present at android-security-14.0.0_r29.
- Android 15: same fix: commit 6b652db8a6d3 in android-security-15.0.0_r13; same PermissionActivity.java and MediaProvider.java changes (surrounding context with ActivityOptions differs); the diff shown does not include MediaStore.java; 8/8 lines present at android-security-15.0.0_r17.
- Android 16: same fix: commit 1b7d4ce446d1 in android-security-16.0.0_r4; same two-file change as 15 at shifted line numbers; 8/8 lines present at android-security-16.0.0_r8.
- Android 17: not affected (not listed by the bulletin); patched region 8/8 present at android-security-17.0.0_r1.
Unknowns
- The concrete scenario in which the PendingIntent launcher differed from the request creator (bug 369105011 is not described in the material).
- Whether PermissionActivity is exported or otherwise reachable with foreign extras.
- Behavior of getPackagesForUid(0) when the extra is missing.
- Whether EXTRA_CALLING_PACKAGE_UID already exists in MediaStore.java on 15/16 or is added elsewhere.
- Which other create request methods (besides CREATE_WRITE_REQUEST_CALL) go through the patched builder.
- Content of the referenced PermissionActivityTest changes.