From b71e39893596a7aa6a8733b9add83452c57b7df9 Mon Sep 17 00:00:00 2001 From: Michael Groover Date: Tue, 16 Jun 2020 13:17:34 -0700 Subject: [PATCH] Relax minimum signature scheme version for apps on system partition Android 11 requires a minimum V2 APK signature for apps targeting SDK version 30+; however some apps on a system partition can only be signed with the V1 signature scheme. This commit relaxes the minimum signature scheme version to allow for these apps on a system partition. Bug: 158728035 Test: atest PackageManagerTest Test: atest PackageManagerTests Test: atest PkgInstallSignatureVerificationTest Change-Id: I1a95fd6894cc937e00ad1ac54d1846b51b48e9cd --- .../android/content/pm/PackageParser.java | 6 ++++-- .../pm/parsing/ParsingPackageUtils.java | 6 ++++-- .../server/pm/PackageManagerService.java | 20 ++++++++++--------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index c8dd4d9d9d51d..6dc74976a0c12 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1374,9 +1374,11 @@ public class PackageParser { } SigningDetails verified; if (skipVerify) { - // systemDir APKs are already trusted, save time by not verifying + // systemDir APKs are already trusted, save time by not verifying; since the signature + // is not verified and some system apps can have their V2+ signatures stripped allow + // pulling the certs from the jar signature. verified = ApkSignatureVerifier.unsafeGetCertsWithoutVerification( - apkPath, minSignatureScheme); + apkPath, SigningDetails.SignatureSchemeVersion.JAR); } else { verified = ApkSignatureVerifier.verify(apkPath, minSignatureScheme); } diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 317107829623e..bc9c71e7a68e9 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2748,9 +2748,11 @@ public class ParsingPackageUtils { SigningDetails verified; try { if (skipVerify) { - // systemDir APKs are already trusted, save time by not verifying + // systemDir APKs are already trusted, save time by not verifying; since the + // signature is not verified and some system apps can have their V2+ signatures + // stripped allow pulling the certs from the jar signature. verified = ApkSignatureVerifier.unsafeGetCertsWithoutVerification( - baseCodePath, minSignatureScheme); + baseCodePath, SigningDetails.SignatureSchemeVersion.JAR); } else { verified = ApkSignatureVerifier.verify(baseCodePath, minSignatureScheme); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5e5274849fcd6..6cddc9eb674bb 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -12144,15 +12144,17 @@ public class PackageManagerService extends IPackageManager.Stub } } - // Ensure the package is signed with at least the minimum signature scheme version - // required for its target SDK. - int minSignatureSchemeVersion = - ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk( - pkg.getTargetSdkVersion()); - if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) { - throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES, - "No signature found in package of version " + minSignatureSchemeVersion - + " or newer for package " + pkg.getPackageName()); + // If the package is not on a system partition ensure it is signed with at least the + // minimum signature scheme version required for its target SDK. + if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { + int minSignatureSchemeVersion = + ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk( + pkg.getTargetSdkVersion()); + if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) { + throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES, + "No signature found in package of version " + minSignatureSchemeVersion + + " or newer for package " + pkg.getPackageName()); + } } } }