diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 26 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/SharedUserSetting.java | 1 |
2 files changed, 23 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7eeefcbe425d..8bf09451e473 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -10215,10 +10215,14 @@ public class PackageManagerService extends IPackageManager.Stub // if this is is a sharedUser, check to see if the new package is signed by a newer // signing certificate than the existing one, and if so, copy over the new details - if (signatureCheckPs.sharedUser != null - && pkg.mSigningDetails.hasAncestor( + if (signatureCheckPs.sharedUser != null) { + if (pkg.mSigningDetails.hasAncestor( signatureCheckPs.sharedUser.signatures.mSigningDetails)) { - signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails; + signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails; + } + if (signatureCheckPs.sharedUser.signaturesChanged == null) { + signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE; + } } } catch (PackageManagerException e) { if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { @@ -10227,10 +10231,24 @@ public class PackageManagerService extends IPackageManager.Stub // The signature has changed, but this package is in the system // image... let's recover! pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails; + // If the system app is part of a shared user we allow that shared user to change - // signatures as well in part as part of an OTA. + // signatures as well as part of an OTA. We still need to verify that the signatures + // are consistent within the shared user for a given boot, so only allow updating + // the signatures on the first package scanned for the shared user (i.e. if the + // signaturesChanged state hasn't been initialized yet in SharedUserSetting). if (signatureCheckPs.sharedUser != null) { + if (signatureCheckPs.sharedUser.signaturesChanged != null && + compareSignatures( + signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures, + pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) { + throw new PackageManagerException( + INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, + "Signature mismatch for shared user: " + pkgSetting.sharedUser); + } + signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails; + signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE; } // File a report about this. String msg = "System package " + pkg.packageName diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java index b6b94f5e3cab..ca08415f7a77 100644 --- a/services/core/java/com/android/server/pm/SharedUserSetting.java +++ b/services/core/java/com/android/server/pm/SharedUserSetting.java @@ -46,6 +46,7 @@ public final class SharedUserSetting extends SettingBase { final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>(); final PackageSignatures signatures = new PackageSignatures(); + Boolean signaturesChanged; SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) { super(_pkgFlags, _pkgPrivateFlags); |