From 497c05218ae3b30fdd01699e06fba4d04e90659d Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 12 May 2015 13:07:14 -0700 Subject: [PATCH] Ignore abandon after install relinquished. We recently changed the install flow to fully dexopt before renaming the staging directory. This exposed the ability for the session owner to abandon and destroy the stage contents while dexopt was still happening. Due to SELinux rules, the abandon would fail to clean up the stage directory, and PackageManager would "successfully" rename and install that stage, which now only contained the oat/ directory. To avoid this case, we now ignore abandon requests once we've passed the "point of no return" and relinquished our stage over to PackageManagerService. Bug: 20175072 Change-Id: I4ad5b1eba0e38f1315b8330bd95be6e3bc6c635a --- .../android/server/pm/PackageInstallerSession.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 89ca00e2f2295..dcf668d665dd6 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -127,6 +127,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @GuardedBy("mLock") private boolean mPermissionsAccepted = false; @GuardedBy("mLock") + private boolean mRelinquished = false; + @GuardedBy("mLock") private boolean mDestroyed = false; private int mFinalStatus; @@ -557,6 +559,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { user = new UserHandle(userId); } + mRelinquished = true; mPm.installStage(mPackageName, stageDir, stageCid, localObserver, params, installerPackageName, installerUid, user); } @@ -928,6 +931,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void abandon() { + if (mRelinquished) { + Slog.d(TAG, "Ignoring abandon after commit relinquished control"); + return; + } destroyInternal(); dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null); } @@ -958,8 +965,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } if (stageDir != null) { - FileUtils.deleteContents(stageDir); - stageDir.delete(); + mPm.mInstaller.rmPackageDir(stageDir.getAbsolutePath()); } if (stageCid != null) { PackageHelper.destroySdDir(stageCid); @@ -990,6 +996,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { pw.printPair("mProgress", mProgress); pw.printPair("mSealed", mSealed); pw.printPair("mPermissionsAccepted", mPermissionsAccepted); + pw.printPair("mRelinquished", mRelinquished); pw.printPair("mDestroyed", mDestroyed); pw.printPair("mBridges", mBridges.size()); pw.printPair("mFinalStatus", mFinalStatus);