summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java24
-rw-r--r--services/core/java/com/android/server/pm/SharedUserSetting.java1
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 86fc0cf82507..62b997229ab0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11000,6 +11000,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;
@@ -11007,19 +11013,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);