diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 24 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/SharedUserSetting.java | 1 |
2 files changed, 19 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5ff9c95c1a33..864c965af3f6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -11026,6 +11026,12 @@ public class PackageManagerService extends IPackageManager.Stub // We just determined the app is signed correctly, so bring // over the latest parsed certs. pkgSetting.signatures.mSignatures = pkg.mSignatures; + + if (signatureCheckPs.sharedUser != null) { + if (signatureCheckPs.sharedUser.signaturesChanged == null) { + signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE; + } + } } catch (PackageManagerException e) { if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { throw e; @@ -11033,19 +11039,25 @@ public class PackageManagerService extends IPackageManager.Stub // The signature has changed, but this package is in the system // image... let's recover! pkgSetting.signatures.mSignatures = pkg.mSignatures; - // However... if this package is part of a shared user, but it - // doesn't match the signature of the shared user, let's fail. - // What this means is that you can't change the signatures - // associated with an overall shared user, which doesn't seem all - // that unreasonable. + + // If the system app is part of a shared user we allow that shared user to + // change 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 (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures, + if (signatureCheckPs.sharedUser.signaturesChanged != null && + compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { throw new PackageManagerException( INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, "Signature mismatch for shared user: " + pkgSetting.sharedUser); } + + signatureCheckPs.sharedUser.signatures.mSignatures = pkg.mSignatures; + 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 06e020a056fd..74294ea20d76 100644 --- a/services/core/java/com/android/server/pm/SharedUserSetting.java +++ b/services/core/java/com/android/server/pm/SharedUserSetting.java @@ -33,6 +33,7 @@ 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); |