Merge changes from topic "change-shared-user-apk-cert-pi-dev" into pi-dev

* changes:
  Allow changing signing cert for system apps that use shared users
  Revert "Allow shared users to rotate signing certs in an OTA"
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7eeefcb..8bf0945 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 @@
 
                 // 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 @@
                 // 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 b6b94f5..ca08415 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 @@
     final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>();
 
     final PackageSignatures signatures = new PackageSignatures();
+    Boolean signaturesChanged;
 
     SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) {
         super(_pkgFlags, _pkgPrivateFlags);