Allow changing signing cert for system apps that use shared users
This allows changing the signing certificate of system apps that use shared users across an OTA, but still verifies that all signatures within a given boot are consistent for a given shared user. Bug: 72837107 Bug: 77973716 Bug: 74501739 Test: Flashed dev-keys build into slot b and (local) release-keys build into slot a, booted into b, then successfully booted into a without wiping userdata. Test: Same as above, but treated com.android.mtp (uses android.media UID) as PRESIGNED during release signing so it kept dev-keys. Verified it wasn't scanned first and that only that package was rejected. Test: Same as above, but treated com.android.providers.downloads (uses android.media UID) as PRESIGNED during release signing so it kept dev-keys. Verified it was scanned first (out of APKs using this UID) and that only this package was accepted. Verified other APKs using android.media UID that were scanned after were rejected. Change-Id: I2076e8358cae22e45a24aa4c32a1b8dd446679ca Merged-In: I2076e8358cae22e45a24aa4c32a1b8dd446679ca
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user