CVE-2026-45528 AI-generated analysis
platform/frameworks/base, services/core StorageManagerService (getManageSpaceActivityIntent binder API)
StorageManagerService.getManageSpaceActivityIntent now builds the returned PendingIntent through ActivityManagerInternal.getPendingIntentActivityAsApp with the target package name and appInfo.uid instead of calling PendingIntent.getActivity on a package context created inside system_server with the calling identity cleared.
Root cause
In services/core/java/com/android/server/StorageManagerService.java, getManageSpaceActivityIntent cleared the Binder calling identity, obtained a Context for the target package via mContext.createPackageContext(packageName, 0) (Android 14/15) or mContext.createPackageContextAsUser(packageName, /* flags= */ 0, UserHandle.of(UserHandle.getUserId(originalUid))) (Android 16/17), and called PendingIntent.getActivity(targetAppContext, ...). Per the commit message, this let callers obtain a PendingIntent "registered under the target package identity with system privileges". Any caller passing the hasExternalStorageAccess (MANAGE_EXTERNAL_STORAGE) check could reach this path.
How the fix works
- StorageManagerService.java:getManageSpaceActivityIntent: removes the Binder.clearCallingIdentity()/restoreCallingIdentity(token) block and the createPackageContext/createPackageContextAsUser call, so no system-created Context for the target package is used.
- StorageManagerService.java:getManageSpaceActivityIntent: keeps the same Intent (ACTION_DEFAULT, setClassName(packageName, appInfo.manageSpaceActivityName), FLAG_ACTIVITY_NEW_TASK), the same ActivityOptions with MODE_BACKGROUND_ACTIVITY_START_DENIED, and the same flags FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE.
- StorageManagerService.java:getManageSpaceActivityIntent: obtains ActivityManagerInternal via LocalServices.getService(ActivityManagerInternal.class) and calls amInternal.getPendingIntentActivityAsApp(requestCode, intent, flags, options.toBundle(), packageName, appInfo.uid), passing the target package and the uid from the ApplicationInfo resolved for UserHandle.getUserId(originalUid).
- The catch of PackageManager.NameNotFoundException and its IllegalArgumentException("packageName not found") are removed; the pre-existing appInfo == null check (IllegalArgumentException("Invalid packageName")) remains the guard for unknown packages.
Completeness
- The fix covers the single PendingIntent construction site in getManageSpaceActivityIntent; the preceding caller checks (getPackagesForUid, hasExternalStorageAccess on packagesFromUid[0], getApplicationInfo for the caller's user, manageSpaceActivityName null check) are unchanged.
- The intent contents and flags are unchanged; only the way the PendingIntent is created changes. The material shows no other PendingIntent creation sites in StorageManagerService, so nothing else can be judged from it.
- The caller check still only inspects packagesFromUid[0] (acknowledged in the existing comment); this is untouched by the fix.
Behavior changes
- The PendingIntent is created via ActivityManagerInternal.getPendingIntentActivityAsApp with packageName and appInfo.uid instead of from a system_server-created package context with identity cleared.
- A package that resolves via getApplicationInfo but fails createPackageContext no longer yields IllegalArgumentException("packageName not found"); unknown packages still get IllegalArgumentException("Invalid packageName") from the earlier check.
- Binder calling identity is no longer cleared during PendingIntent creation.
Per major
- Android 14: same fix: commit 51b647175642 in android-security-14.0.0_r29 (RESTRICT AUTOMERGE), replaces createPackageContext-based PendingIntent.getActivity with getPendingIntentActivityAsApp.
- Android 15: same fix: commit 8c8709a5ad8c in android-security-15.0.0_r17, diff identical to Android 14 (old code used createPackageContext).
- Android 16: same fix: commit 84d85dbe121f in android-security-16.0.0_r8; added code identical to 14/15, the removed code used createPackageContextAsUser(packageName, /* flags= */ 0, UserHandle.of(UserHandle.getUserId(originalUid))).
- Android 17: same fix: commit 43ef4a09e448 in android-security-17.0.0_r1; identical to Android 16 (createPackageContextAsUser variant removed).
Unknowns
- The implementation of ActivityManagerInternal.getPendingIntentActivityAsApp and the exact PendingIntent ownership/send semantics it enforces are not shown in the material.
- Whether LocalServices.getService(ActivityManagerInternal.class) can return null at this call site is not shown; the diff adds no null handling.
- The commit has an empty Test: field; no test coverage is shown.
- The material does not show whether the import changes (ActivityManagerInternal, LocalServices, possibly unused PackageManager) were part of the same commit.