From a4945fcf4b29e6728ce8bae3970f42a75898d0e2 Mon Sep 17 00:00:00 2001 From: Songchun Fan Date: Tue, 28 Jun 2022 01:06:53 +0000 Subject: [PATCH 1/3] [RESTRICT AUTOMERGE] Revert "Fix NPE" This reverts commit f562aadd77298ec019dc410e395a512bbb57c720. Reason for revert: Reverting CVE-2021-39624 on qt-dev Change-Id: Ida84f497eb188b4923acbe8acdbe4d47427aa24e --- .../java/com/android/server/pm/PackageInstallerService.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 3f6ebecdcf0f8..7c1ac2737469a 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -332,10 +332,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements // Their staging dirs will be removed too PackageInstallerSession root = !session.hasParentSessionId() ? session : mSessions.get(session.getParentSessionId()); - if (root == null) { - Slog.e(TAG, "freeStageDirs: found an orphaned session: " - + session.sessionId + " parent=" + session.getParentSessionId()); - } else if (!root.isDestroyed() && + if (!root.isDestroyed() && (!root.isStaged() || (root.isStaged() && root.isStagedSessionReady()))) { root.abandon(); From 6b86ed849780dedd0f9319833e53bb194d74fefa Mon Sep 17 00:00:00 2001 From: Songchun Fan Date: Tue, 28 Jun 2022 01:08:02 +0000 Subject: [PATCH 2/3] [RESTRICT AUTOMERGE] Revert "Don't abandon child sessions (1/n)" Revert submission 16575908-dont_abandon_child_qt_dev Reason for revert: Reverting CVE-2021-39624 on qt-dev Reverted Changes: I4ede6b7a4:Persist destroyed staged sessions until they are c... Ib0ba9f378:Don't abandon child sessions (1/n) Change-Id: I7915e3f0ba6dd8430a9b938a518aeeeb4d6b1805 --- .../com/android/server/pm/PackageInstallerService.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 7c1ac2737469a..ac56020f95a14 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -330,13 +330,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements if (age >= MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS) { // Aggressively close old sessions because we are running low on storage // Their staging dirs will be removed too - PackageInstallerSession root = !session.hasParentSessionId() - ? session : mSessions.get(session.getParentSessionId()); - if (!root.isDestroyed() && - (!root.isStaged() || (root.isStaged() && root.isStagedSessionReady()))) - { - root.abandon(); - } + session.abandon(); } else { // Session is new enough, so it deserves to be kept even on low storage unclaimedStagingDirsOnVolume.remove(session.stageDir); From dde06fe41d59d7106c604fc848d46be3d17d2942 Mon Sep 17 00:00:00 2001 From: Songchun Fan Date: Tue, 28 Jun 2022 01:08:51 +0000 Subject: [PATCH 3/3] [RESTRICT AUTOMERGE] Revert "Revert "Revert "[pm] remove old stage dirs on low storage""" This reverts commit 3e28df68fa23add99c84507bdcd9f0270311f1fc. Reason for revert: Reverting CVE-2021-39624 on qt-dev Change-Id: I26c0abd06e2a49e05f45d153c4247f7c0a269897 --- .../server/pm/PackageInstallerService.java | 50 ++----------------- .../server/pm/PackageInstallerSession.java | 17 +------ .../server/pm/PackageManagerService.java | 3 -- 3 files changed, 7 insertions(+), 63 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index ac56020f95a14..78e88be85cc8e 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -129,9 +129,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements private static final long MAX_ACTIVE_SESSIONS = 1024; /** Upper bound on number of historical sessions for a UID */ private static final long MAX_HISTORICAL_SESSIONS = 1048576; - /** Destroy sessions older than this on storage free request */ - private static final long MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS = 8 * DateUtils.HOUR_IN_MILLIS; - private final Context mContext; private final PackageManagerService mPm; @@ -278,28 +275,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @GuardedBy("mSessions") private void reconcileStagesLocked(String volumeUuid) { - final ArraySet unclaimedStages = getStagingDirsOnVolume(volumeUuid); + final File stagingDir = getTmpSessionDir(volumeUuid); + final ArraySet unclaimedStages = newArraySet( + stagingDir.listFiles(sStageFilter)); + // Ignore stages claimed by active sessions for (int i = 0; i < mSessions.size(); i++) { final PackageInstallerSession session = mSessions.valueAt(i); unclaimedStages.remove(session.stageDir); } - removeStagingDirs(unclaimedStages); - } - private ArraySet getStagingDirsOnVolume(String volumeUuid) { - final File stagingDir = getTmpSessionDir(volumeUuid); - final ArraySet stagingDirs = newArraySet(stagingDir.listFiles(sStageFilter)); - // We also need to clean up orphaned staging directory for staged sessions - final File stagedSessionStagingDir = Environment.getDataStagingDirectory(volumeUuid); - stagingDirs.addAll(newArraySet(stagedSessionStagingDir.listFiles())); - return stagingDirs; - } - - - private void removeStagingDirs(ArraySet stagingDirsToRemove) { // Clean up orphaned staging directories - for (File stage : stagingDirsToRemove) { + for (File stage : unclaimedStages) { Slog.w(TAG, "Deleting orphan stage " + stage); synchronized (mPm.mInstallLock) { mPm.removeCodePathLI(stage); @@ -313,33 +300,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } - /** - * Called to free up some storage space from obsolete installation files - */ - public void freeStageDirs(String volumeUuid) { - final ArraySet unclaimedStagingDirsOnVolume = getStagingDirsOnVolume(volumeUuid); - final long currentTimeMillis = System.currentTimeMillis(); - synchronized (mSessions) { - for (int i = 0; i < mSessions.size(); i++) { - final PackageInstallerSession session = mSessions.valueAt(i); - if (!unclaimedStagingDirsOnVolume.contains(session.stageDir)) { - // Only handles sessions stored on the target volume - continue; - } - final long age = currentTimeMillis - session.createdMillis; - if (age >= MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS) { - // Aggressively close old sessions because we are running low on storage - // Their staging dirs will be removed too - session.abandon(); - } else { - // Session is new enough, so it deserves to be kept even on low storage - unclaimedStagingDirsOnVolume.remove(session.stageDir); - } - } - } - removeStagingDirs(unclaimedStagingDirsOnVolume); - } - public static boolean isStageName(String name) { final boolean isFile = name.startsWith("vmdl") && name.endsWith(".tmp"); final boolean isContainer = name.startsWith("smdl") && name.endsWith(".tmp"); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 413ee3256f0ac..4e91f7d29ec7a 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2097,7 +2097,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { + mParentSessionId + " and may not be abandoned directly."); } synchronized (mLock) { - assertCallerIsOwnerOrRootOrSystemLocked(); + assertCallerIsOwnerOrRootLocked(); + if (isStagedAndInTerminalState()) { // We keep the session in the database if it's in a finalized state. It will be // removed by PackageInstallerService when the last update time is old enough. @@ -2124,20 +2125,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null); } - /** - * Check if the caller is the owner of this session. Otherwise throw a - * {@link SecurityException}. - */ - @GuardedBy("mLock") - private void assertCallerIsOwnerOrRootOrSystemLocked() { - final int callingUid = Binder.getCallingUid(); - if (callingUid != Process.ROOT_UID && callingUid != mInstallerUid - && callingUid != Process.SYSTEM_UID) { - throw new SecurityException("Session does not belong to uid " + callingUid); - } - } - - @Override public boolean isMultiPackage() { return params.isMultiPackage; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 3549db4297583..af91d5973e6a6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4875,9 +4875,6 @@ public class PackageManagerService extends IPackageManager.Stub InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) { return; } - // 12. Clear temp install session files - mInstallerService.freeStageDirs(volumeUuid); - } else { try { mInstaller.freeCache(volumeUuid, bytes, 0, 0);