diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index eb005ce407774..9972a8c22e31e 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -15,6 +15,7 @@ --> set1 = new HashSet(); + for (Signature sig : s1) { + set1.add(sig); } - return PackageManager.SIGNATURE_MATCH; + HashSet set2 = new HashSet(); + for (Signature sig : s2) { + set2.add(sig); + } + // Make sure s2 contains all signatures in s1. + if (set1.equals(set2)) { + return PackageManager.SIGNATURE_MATCH; + } + return PackageManager.SIGNATURE_NO_MATCH; } public String[] getPackagesForUid(int uid) { @@ -2501,6 +2499,9 @@ class PackageManagerService extends IPackageManager.Stub { mLastScanError = pp.getParseError(); return false; } + } else { + // Lets implicitly assign existing certificates. + pkg.mSignatures = ps.signatures.mSignatures; } } return true; @@ -2629,28 +2630,27 @@ class PackageManagerService extends IPackageManager.Stub { } private boolean verifySignaturesLP(PackageSetting pkgSetting, - PackageParser.Package pkg, int parseFlags, boolean updateSignature) { - if (pkg.mSignatures != null) { - if (!pkgSetting.signatures.updateSignatures(pkg.mSignatures, - updateSignature)) { - Slog.e(TAG, "Package " + pkg.packageName - + " signatures do not match the previously installed version; ignoring!"); - mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; - return false; - } - - if (pkgSetting.sharedUser != null) { - if (!pkgSetting.sharedUser.signatures.mergeSignatures( - pkg.mSignatures, updateSignature)) { + PackageParser.Package pkg) { + if (pkgSetting.signatures.mSignatures != null) { + // Already existing package. Make sure signatures match + if (checkSignaturesLP(pkgSetting.signatures.mSignatures, pkg.mSignatures) != + PackageManager.SIGNATURE_MATCH) { Slog.e(TAG, "Package " + pkg.packageName - + " has no signatures that match those in shared user " - + pkgSetting.sharedUser.name + "; ignoring!"); - mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; + + " signatures do not match the previously installed version; ignoring!"); + mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; return false; } + } + // Check for shared user signatures + if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { + if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures, + pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { + Slog.e(TAG, "Package " + pkg.packageName + + " has no signatures that match those in shared user " + + pkgSetting.sharedUser.name + "; ignoring!"); + mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; + return false; } - } else { - pkg.mSignatures = pkgSetting.signatures.mSignatures; } return true; } @@ -2996,10 +2996,8 @@ class PackageManagerService extends IPackageManager.Stub { pkg.applicationInfo.uid = pkgSetting.userId; pkg.mExtras = pkgSetting; - if (!verifySignaturesLP(pkgSetting, pkg, parseFlags, - (scanMode&SCAN_UPDATE_SIGNATURE) != 0)) { + if (!verifySignaturesLP(pkgSetting, pkg)) { if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { - mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; return null; } // The signature has changed, but this package is in the system @@ -3011,8 +3009,9 @@ class PackageManagerService extends IPackageManager.Stub { // associated with an overall shared user, which doesn't seem all // that unreasonable. if (pkgSetting.sharedUser != null) { - if (!pkgSetting.sharedUser.signatures.mergeSignatures( - pkg.mSignatures, false)) { + if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures, + pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { + Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser); mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; return null; } @@ -5543,7 +5542,7 @@ class PackageManagerService extends IPackageManager.Stub { // First find the old package info and check signatures synchronized(mPackages) { oldPackage = mPackages.get(pkgName); - if (checkSignaturesLP(pkg.mSignatures, oldPackage.mSignatures) + if (checkSignaturesLP(oldPackage.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; return; @@ -5571,7 +5570,6 @@ class PackageManagerService extends IPackageManager.Stub { oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName); } - parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING; // First delete the existing package while retaining the data directory if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA, res.removedInfo)) { @@ -5595,20 +5593,7 @@ class PackageManagerService extends IPackageManager.Stub { } } - if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { - // If we deleted an exisiting package, the old source and resource files that we - // were keeping around in case we needed them (see below) can now be deleted. - // This info will be set on the res.removedInfo to clean up later on as post - // install action. - - //update signature on the new package setting - //this should always succeed, since we checked the - //signature earlier. - synchronized(mPackages) { - verifySignaturesLP(mSettings.mPackages.get(pkgName), pkg, - parseFlags, true); - } - } else { + if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { // remove package from internal structures. Note that we want deletePackageX to // delete the package data and cache directories that it created in // scanPackageLocked, unless those directories existed before we even tried to @@ -5627,19 +5612,23 @@ class PackageManagerService extends IPackageManager.Stub { Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName); return; } - PackageInstalledInfo restoreRes = new PackageInstalledInfo(); - restoreRes.removedInfo = new PackageRemovedInfo(); // Parse old package - parseFlags &= ~PackageManager.INSTALL_REPLACE_EXISTING; - scanPackageLI(restoreFile, parseFlags, scanMode); + boolean oldOnSd = isExternal(deletedPackage); + int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | + (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) | + (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0); + int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE; + if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode) == null) { + Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade"); + return; + } + // Restore of old package succeeded. Update permissions. synchronized (mPackages) { updatePermissionsLP(deletedPackage.packageName, deletedPackage, true, false); mSettings.writeLP(); } - if (restoreRes.returnCode != PackageManager.INSTALL_SUCCEEDED) { - Slog.e(TAG, "Failed restoring pkg : " + pkgName + " after failed upgrade"); - } + Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); } } } @@ -5691,15 +5680,7 @@ class PackageManagerService extends IPackageManager.Stub { updatedSettings = true; } - if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { - //update signature on the new package setting - //this should always succeed, since we checked the - //signature earlier. - synchronized(mPackages) { - verifySignaturesLP(mSettings.mPackages.get(packageName), pkg, - parseFlags, true); - } - } else { + if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { // Re installation failed. Restore old information // Remove new pkg information if (newPackage != null) { @@ -5781,7 +5762,7 @@ class PackageManagerService extends IPackageManager.Stub { boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0); boolean replace = false; - int scanMode = SCAN_MONITOR | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE + int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE | (newInstall ? SCAN_NEW_INSTALL : 0); // Result object to be returned res.returnCode = PackageManager.INSTALL_SUCCEEDED; @@ -5911,6 +5892,10 @@ class PackageManagerService extends IPackageManager.Stub { return ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); } + private boolean isExternal(PackageParser.Package pkg) { + return ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); + } + private void extractPublicFiles(PackageParser.Package newPackage, File publicZipFile) throws IOException { final ZipOutputStream publicZipOutStream = @@ -7345,101 +7330,6 @@ class PackageManagerService extends IPackageManager.Stub { } } - /** - * If any of the given 'sigs' is contained in the existing signatures, - * then completely replace the current signatures with the ones in - * 'sigs'. This is used for updating an existing package to a newly - * installed version. - */ - boolean updateSignatures(Signature[] sigs, boolean update) { - if (mSignatures == null) { - if (update) { - assignSignatures(sigs); - } - return true; - } - if (sigs == null) { - return false; - } - - for (int i=0; i