From dbe0dd160e93feef1335830a36e86ae83b19b793 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 26 Mar 2015 15:38:29 -0700 Subject: When scanning unbundled apps, only install the expected APK tree We now make sure, when scanning post-factory app installs, that we do not accidentally activate a "leaked" or otherwise superfluous APK tree that the scan algorithm happens to encounter before the one that we expect a priori based on the persisted package-installation state. When we find such an extraneous installation we ignore it in favor of the expected one, similarly to the policy used when collecting system-bundled packages that have been updated. Even if we find an unexpected APK for the package, if the expected one turns out to be absent we fall back to the existing "we thought this app was present and now it isn't" logic. Bug 19602471 Change-Id: I141a93661946176c05d8cf52a123bdf75c8eef74 --- .../android/server/pm/PackageManagerService.java | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index cc0a30a508e6..6498dcc2a44d 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -271,6 +271,7 @@ public class PackageManagerService extends IPackageManager.Stub { static final int SCAN_TRUSTED_OVERLAY = 1<<9; static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; static final int SCAN_REPLACING = 1<<11; + static final int SCAN_REQUIRE_KNOWN = 1<<12; static final int REMOVE_CHATTY = 1<<16; @@ -1646,10 +1647,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (!mOnlyCore) { EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, SystemClock.uptimeMillis()); - scanDirLI(mAppInstallDir, 0, scanFlags, 0); + scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, - scanFlags, 0); + scanFlags | SCAN_REQUIRE_KNOWN, 0); /** * Remove disable package settings for any updated system @@ -5349,6 +5350,28 @@ public class PackageManagerService extends IPackageManager.Stub { + " already installed. Skipping duplicate."); } + // If we're only installing presumed-existing packages, require that the + // scanned APK is both already known and at the path previously established + // for it. Previously unknown packages we pick up normally, but if we have an + // a priori expectation about this package's install presence, enforce it. + if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { + PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); + if (known != null) { + if (DEBUG_PACKAGE_SCANNING) { + Log.d(TAG, "Examining " + pkg.codePath + + " and requiring known paths " + known.codePathString + + " & " + known.resourcePathString); + } + if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) + || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { + throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, + "Application package " + pkg.packageName + + " found at " + pkg.applicationInfo.getCodePath() + + " but expected at " + known.codePathString + "; ignoring."); + } + } + } + // Initialize package source and resource directories File destCodeFile = new File(pkg.applicationInfo.getCodePath()); File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); -- cgit v1.2.3-59-g8ed1b