CVE-2026-0055 AI-generated analysis
platform/frameworks/base, services/core PackageInstallerService (package installer session creation)
PackageInstallerService.createSessionInternal now checks the caller-supplied SessionParams.volumeUuid with StorageManager.convert() when INSTALL_FORCE_VOLUME_UUID is set. Invalid values are rejected with an IllegalArgumentException when the session is created, instead of passing into later install handling.
Root cause
In services/core/java/com/android/server/pm/PackageInstallerService.java, createSessionInternal picks the install location in one of three branches. In the INSTALL_FORCE_VOLUME_UUID branch, the code only OR-ed INSTALL_INTERNAL into params.installFlags. It kept params.volumeUuid exactly as the caller supplied it and never checked that it was a well-formed volume UUID. The commit message's test output shows a value such as "../../../data" now being rejected. Per the commit message, before the fix such a value was used later in the stack and crashed the system ("fails early instead of crashing system later").
How the fix works
- services/core/java/com/android/server/pm/PackageInstallerService.java: in createSessionInternal, inside the `else if ((params.installFlags & PackageManager.INSTALL_FORCE_VOLUME_UUID) != 0)` branch and right after `params.installFlags |= PackageManager.INSTALL_INTERNAL;`, the fix calls `StorageManager.convert(params.volumeUuid)` inside a try block.
- If StorageManager.convert throws IllegalArgumentException, the fix throws a new IllegalArgumentException with the message "Invalid volumeUuid value in session params: " + params.volumeUuid. createSessionInternal then stops before the session is allocated and the synchronized(mSessions) block runs.
- The result of the conversion is discarded. The call serves only as a validity check. StorageManager.convert(String) parses a volume UUID string into a UUID and throws IllegalArgumentException on malformed input (general platform knowledge).
Completeness
- Covers only the INSTALL_FORCE_VOLUME_UUID branch of createSessionInternal. The check is a single call added there, and no other file is changed.
- The INSTALL_INTERNAL branch (lines 869-872) still keeps params.volumeUuid as the caller supplied it and does not run the new check. The material does not show whether that value is used downstream.
- The final else branch overwrites params.volumeUuid with InstallLocationUtils.resolveInstallVolume, so caller input does not reach later code on that path.
- The downstream code that crashed is not changed. The fix rejects bad input early at the entry point; it does not harden the later use.
- The whole location-selection block sits inside an enclosing conditional that closes at line 897. The material does not show what guards it, so a path that skips the block would not be covered.
Behavior changes
- Creating a session with INSTALL_FORCE_VOLUME_UUID and a volumeUuid that StorageManager.convert rejects now fails immediately with IllegalArgumentException("Invalid volumeUuid value in session params: <value>") instead of succeeding. The commit message shows the `install` shell command reporting this exception.
- No change for valid UUIDs or for sessions that do not use INSTALL_FORCE_VOLUME_UUID.
Per major
- Android 14: same fix: commit 06fb4af542b7 in android-security-14.0.0_r28 (cherry-pick of fe2d4eb0555a), identical 8-line hunk at line 874; 4/4 lines present at android-security-14.0.0_r29.
- Android 15: same fix: commit 613fa6465e4d in android-security-15.0.0_r16, identical hunk at line 945; 4/4 lines present at android-security-15.0.0_r17.
- Android 16: same fix: commit 62ec466efd80 in android-security-16.0.0_r7, identical hunk at line 956; 4/4 lines present at android-security-16.0.0_r8.
- Android 17: same fix: commit c17553943026 in android-17.0.0_r1 (base), identical hunk; 4/4 lines present at android-security-17.0.0_r1.
Unknowns
- Which downstream code used the invalid volumeUuid and crashed the system (the material only says it crashed 'later').
- Whether unprivileged callers can set INSTALL_FORCE_VOLUME_UUID or whether it is permission-gated.
- What conditional encloses the location-selection block (closing brace at line 897) and whether any session-creation path bypasses it.
- Whether the INSTALL_INTERNAL branch ever uses the caller-supplied volumeUuid downstream.
- Whether StorageManager is already imported in PackageInstallerService.java on each branch (imports are not shown).