From 61fc857a22f3e11f2d8095041ee7b006106064f0 Mon Sep 17 00:00:00 2001 From: Danny Lin Date: Sat, 16 Oct 2021 05:27:57 -0700 Subject: [PATCH 3/4] Add support for app signature spoofing This is needed by microG GmsCore to pretend to be the official Google Play Services package, because client apps check the package signature to make sure it matches Google's official certificate. This was forward-ported from the Android 10 patch by gudenau: https://github.com/microg/android_packages_apps_GmsCore/pull/957 Changes made for Android 11: - Updated PackageInfo calls - Added new permission to public API surface, needed for PermissionController which is now an updatable APEX on 11 - Added a dummy permission group to allow users to manage the permission through the PermissionController UI (by Vachounet ) - Updated location provider comment for conciseness Changes made for Android 12: - Moved mayFakeSignature into lock-free Computer subclass - Always get permissions for packages that request signature spoofing (otherwise permissions are usually ommitted and thus the permission check doesn't work properly) - Optimize mayFakeSignature check order to improve performance Changes made for Android 13: - Computer subclass is now an independent class. Change-Id: Ied7d6ce0b83a2d2345c3abba0429998d86494a88 --- core/api/current.txt | 2 ++ core/res/AndroidManifest.xml | 15 ++++++++++ core/res/res/values/strings.xml | 12 ++++++++ .../com/android/server/pm/ComputerEngine.java | 30 +++++++++++++++++-- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 487e57d114c9..04e69741b9fd 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -87,6 +87,7 @@ package android { field public static final String DUMP = "android.permission.DUMP"; field public static final String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR"; field public static final String FACTORY_TEST = "android.permission.FACTORY_TEST"; + field public static final String FAKE_PACKAGE_SIGNATURE = "android.permission.FAKE_PACKAGE_SIGNATURE"; field public static final String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE"; field public static final String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS"; field public static final String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED"; @@ -222,6 +223,7 @@ package android { field public static final String CALL_LOG = "android.permission-group.CALL_LOG"; field public static final String CAMERA = "android.permission-group.CAMERA"; field public static final String CONTACTS = "android.permission-group.CONTACTS"; + field public static final String FAKE_PACKAGE = "android.permission-group.FAKE_PACKAGE"; field public static final String LOCATION = "android.permission-group.LOCATION"; field public static final String MICROPHONE = "android.permission-group.MICROPHONE"; field public static final String NEARBY_DEVICES = "android.permission-group.NEARBY_DEVICES"; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 6a80d1cb62a7..189c5c223cd0 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3564,6 +3564,21 @@ android:description="@string/permdesc_getPackageSize" android:protectionLevel="normal" /> + + + + + + diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 9410e0682106..7ed7a03f1b61 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -977,6 +977,18 @@ + + Spoof package signature + + Allows the app to pretend to be a different app. Malicious applications might be able to use this to access private application data. Legitimate uses include an emulator pretending to be what it emulates. Grant this permission with caution only! + + Spoof package signature + + allow to spoof package signature + + Allow + <b>%1$s</b> to spoof package signature? + disable or modify status bar diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java index 46b7460dff1b..40549962436f 100644 --- a/services/core/java/com/android/server/pm/ComputerEngine.java +++ b/services/core/java/com/android/server/pm/ComputerEngine.java @@ -1603,6 +1603,29 @@ public class ComputerEngine implements Computer { return result; } + private boolean requestsFakeSignature(AndroidPackage p) { + return p.getMetaData() != null && + p.getMetaData().getString("fake-signature") != null; + } + + private PackageInfo mayFakeSignature(AndroidPackage p, PackageInfo pi, + Set permissions) { + try { + if (p.getMetaData() != null && + p.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) { + String sig = p.getMetaData().getString("fake-signature"); + if (sig != null && + permissions.contains("android.permission.FAKE_PACKAGE_SIGNATURE")) { + pi.signatures = new Signature[] {new Signature(sig)}; + } + } + } catch (Throwable t) { + // We should never die because of any failures, this is system code! + Log.w("PackageManagerService.FAKE_PACKAGE_SIGNATURE", t); + } + return pi; + } + public final PackageInfo generatePackageInfo(PackageStateInternal ps, @PackageManager.PackageInfoFlagsBits long flags, int userId) { if (!mUserManager.exists(userId)) return null; @@ -1632,13 +1655,14 @@ public class ComputerEngine implements Computer { final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY : mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.getAppId())); // Compute granted permissions only if package has requested permissions - final Set permissions = ((flags & PackageManager.GET_PERMISSIONS) == 0 + final Set permissions = (((flags & PackageManager.GET_PERMISSIONS) == 0 + && !requestsFakeSignature(p)) || ArrayUtils.isEmpty(p.getRequestedPermissions())) ? Collections.emptySet() : mPermissionManager.getGrantedPermissions(ps.getPackageName(), userId); - PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags, + PackageInfo packageInfo = mayFakeSignature(p, PackageInfoUtils.generate(p, gids, flags, state.getFirstInstallTime(), ps.getLastUpdateTime(), permissions, state, userId, - ps); + ps), permissions); if (packageInfo == null) { return null; -- 2.39.2