From 9d89543d48b1bd286355f3b2730bee954c8dda1f Mon Sep 17 00:00:00 2001 From: Mathew Inwood Date: Wed, 4 Apr 2018 16:08:21 +0100 Subject: [PATCH] Exempt platform-cert signed apps from hidden API checks. This means that APKs signed with the platform cert are allowed to use hidden APIs, even if they are not on the package whitelist, and if they are not in the system image. It will also allow a number of packages to be removed from the package whitelist. Also remove all platform cert signed apps from the package whitelist, as there is no longer any need for them to be in there. Bug: 64382372 Test: device boots Change-Id: Id805419918de51f946c1f592581bab36ae79de83 --- .../android/content/pm/ApplicationInfo.java | 26 ++++++-- data/etc/hiddenapi-package-whitelist.xml | 65 +------------------ .../server/pm/PackageManagerService.java | 15 ++++- 3 files changed, 36 insertions(+), 70 deletions(-) diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index e85058df82509..aa0bd84a23a54 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -590,26 +590,33 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public static final int PRIVATE_FLAG_VIRTUAL_PRELOAD = 1 << 16; /** - * Value for {@linl #privateFlags}: whether this app is pre-installed on the + * Value for {@link #privateFlags}: whether this app is pre-installed on the * OEM partition of the system image. * @hide */ public static final int PRIVATE_FLAG_OEM = 1 << 17; /** - * Value for {@linl #privateFlags}: whether this app is pre-installed on the + * Value for {@link #privateFlags}: whether this app is pre-installed on the * vendor partition of the system image. * @hide */ public static final int PRIVATE_FLAG_VENDOR = 1 << 18; /** - * Value for {@linl #privateFlags}: whether this app is pre-installed on the + * Value for {@link #privateFlags}: whether this app is pre-installed on the * product partition of the system image. * @hide */ public static final int PRIVATE_FLAG_PRODUCT = 1 << 19; + /** + * Value for {@link #privateFlags}: whether this app is signed with the + * platform key. + * @hide + */ + public static final int PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY = 1 << 20; + /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, @@ -629,6 +636,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_PRIVILEGED, PRIVATE_FLAG_PRODUCT, PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, + PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY, PRIVATE_FLAG_STATIC_SHARED_LIBRARY, PRIVATE_FLAG_VENDOR, PRIVATE_FLAG_VIRTUAL_PRELOAD, @@ -1658,6 +1666,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(packageName); } + private boolean isAllowedToUseHiddenApis() { + return isSignedWithPlatformKey() + || (isPackageWhitelistedForHiddenApis() && (isSystemApp() || isUpdatedSystemApp())); + } + /** * @hide */ @@ -1665,7 +1678,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) { return mHiddenApiPolicy; } - if (isPackageWhitelistedForHiddenApis() && (isSystemApp() || isUpdatedSystemApp())) { + if (isAllowedToUseHiddenApis()) { return HIDDEN_API_ENFORCEMENT_NONE; } return HIDDEN_API_ENFORCEMENT_BLACK; @@ -1757,6 +1770,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE) != 0; } + /** @hide */ + public boolean isSignedWithPlatformKey() { + return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY) != 0; + } + /** @hide */ @TestApi public boolean isPrivilegedApp() { diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml index 95aff9a6bd229..4e09c69b6779f 100644 --- a/data/etc/hiddenapi-package-whitelist.xml +++ b/data/etc/hiddenapi-package-whitelist.xml @@ -17,66 +17,28 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -85,36 +47,13 @@ which apps should be allowed to access the entire private API. - - - - - - - - - - - - - - - - - - - - - - - diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 2c98da3a49042..a7fc8837ecb90 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -8700,7 +8700,7 @@ public class PackageManagerService extends IPackageManager.Stub disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */, null /* originalPkgSetting */, null, parseFlags, scanFlags, (pkg == mPlatformPackage), user); - applyPolicy(pkg, parseFlags, scanFlags); + applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage); scanPackageOnlyLI(request, mFactoryTest, -1L); } } @@ -10019,7 +10019,7 @@ public class PackageManagerService extends IPackageManager.Stub scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg); synchronized (mPackages) { - applyPolicy(pkg, parseFlags, scanFlags); + applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage); assertPackageIsValid(pkg, parseFlags, scanFlags); SharedUserSetting sharedUserSetting = null; @@ -10699,7 +10699,7 @@ public class PackageManagerService extends IPackageManager.Stub * ideally be static, but, it requires locks to read system state. */ private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags, - final @ScanFlags int scanFlags) { + final @ScanFlags int scanFlags, PackageParser.Package platformPkg) { if ((scanFlags & SCAN_AS_SYSTEM) != 0) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; if (pkg.applicationInfo.isDirectBootAware()) { @@ -10785,6 +10785,15 @@ public class PackageManagerService extends IPackageManager.Stub pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT; } + // Check if the package is signed with the same key as the platform package. + if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) || + (platformPkg != null && compareSignatures( + platformPkg.mSigningDetails.signatures, + pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH)) { + pkg.applicationInfo.privateFlags |= + ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY; + } + if (!isSystemApp(pkg)) { // Only system apps can use these features. pkg.mOriginalPackages = null;