From 39747538c64e7f9740396d1d89fafdff1b66a63a Mon Sep 17 00:00:00 2001 From: Jackal Guo Date: Wed, 30 Jun 2021 13:27:52 +0800 Subject: [PATCH] Apply package visibility to PACKAGE_DATA_CLEARED Intent ACTION_PACKAGE_DATA_CLEARED is sent without the allowlist so it may potentially leakage the package information. Bug: 191291133 Test: atest AppEnumerationTests Change-Id: Ica10615db22c0bc0eb4fba550bc069031f18c9a9 --- .../android/app/ActivityManagerInternal.java | 2 +- .../content/pm/PackageManagerInternal.java | 15 +++++++++++++++ .../server/am/ActivityManagerService.java | 17 ++++++++++------- .../android/server/am/PendingIntentRecord.java | 3 ++- .../server/pm/PackageManagerService.java | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index d5f51adc2297c..7145c0fe35bf5 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -377,7 +377,7 @@ public abstract class ActivityManagerInternal { IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, @UserIdInt int userId, boolean allowBackgroundActivityStarts, - @Nullable IBinder backgroundActivityStartsToken); + @Nullable IBinder backgroundActivityStartsToken, @Nullable int[] broadcastAllowList); public abstract ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, boolean fgRequired, String callingPackage, diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index 7d80bb56d4bdc..230e380af108b 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -39,6 +39,7 @@ import android.os.HandlerExecutor; import android.os.IBinder; import android.os.Looper; import android.os.PersistableBundle; +import android.os.Process; import android.util.ArrayMap; import android.util.ArraySet; import android.util.SparseArray; @@ -719,6 +720,20 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP */ public abstract boolean filterAppAccess(int uid, int callingUid); + /** + * Fetches all app Ids that a given application is currently visible to the provided user. + * + *

+ * Note: This only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} + * as all other UIDs can already see all applications. + *

+ * + * If the app is visible to all UIDs, null is returned. If the app is not visible to any + * applications, the int array will be empty. + */ + @Nullable + public abstract int[] getVisibilityAllowList(@NonNull String packageName, int userId); + /** Returns whether the given package was signed by the platform */ public abstract boolean isPlatformSigned(String pkg); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1e7f58a1d4976..785c626da1660 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3536,15 +3536,17 @@ public class ActivityManagerService extends IActivityManager.Stub intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1); intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId); + final int[] visibilityAllowList = + mPackageManagerInt.getVisibilityAllowList(packageName, resolvedUserId); if (isInstantApp) { intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); broadcastIntentInPackage("android", null, SYSTEM_UID, uid, pid, intent, null, null, 0, null, null, permission.ACCESS_INSTANT_APPS, null, - false, false, resolvedUserId, false, null); + false, false, resolvedUserId, false, null, visibilityAllowList); } else { broadcastIntentInPackage("android", null, SYSTEM_UID, uid, pid, intent, null, null, 0, null, null, null, null, false, false, resolvedUserId, - false, null); + false, null, visibilityAllowList); } if (observer != null) { @@ -13653,7 +13655,8 @@ public class ActivityManagerService extends IActivityManager.Stub IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, int userId, boolean allowBackgroundActivityStarts, - @Nullable IBinder backgroundActivityStartsToken) { + @Nullable IBinder backgroundActivityStartsToken, + @Nullable int[] broadcastAllowList) { synchronized(this) { intent = verifyBroadcastLocked(intent); @@ -13665,8 +13668,7 @@ public class ActivityManagerService extends IActivityManager.Stub resultTo, resultCode, resultData, resultExtras, requiredPermissions, null, OP_NONE, bOptions, serialized, sticky, -1, uid, realCallingUid, realCallingPid, userId, allowBackgroundActivityStarts, - backgroundActivityStartsToken, - null /* broadcastAllowList */); + backgroundActivityStartsToken, broadcastAllowList); } finally { Binder.restoreCallingIdentity(origId); } @@ -15851,13 +15853,14 @@ public class ActivityManagerService extends IActivityManager.Stub IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, int userId, boolean allowBackgroundActivityStarts, - @Nullable IBinder backgroundActivityStartsToken) { + @Nullable IBinder backgroundActivityStartsToken, + @Nullable int[] broadcastAllowList) { synchronized (ActivityManagerService.this) { return ActivityManagerService.this.broadcastIntentInPackage(packageName, featureId, uid, realCallingUid, realCallingPid, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermission, bOptions, serialized, sticky, userId, allowBackgroundActivityStarts, - backgroundActivityStartsToken); + backgroundActivityStartsToken, broadcastAllowList); } } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index f7c777e9cd6cd..092b5dfbb399f 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -468,7 +468,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { key.featureId, uid, callingUid, callingPid, finalIntent, resolvedType, finishedReceiver, code, null, null, requiredPermission, options, (finishedReceiver != null), false, - userId, allowedByToken || allowTrampoline, bgStartsToken); + userId, allowedByToken || allowTrampoline, bgStartsToken, + null /* broadcastAllowList */); if (sent == ActivityManager.BROADCAST_SUCCESS) { sendFinish = false; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9085e498af19f..70d12f32fe5ee 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -27126,6 +27126,18 @@ public class PackageManagerService extends IPackageManager.Stub return mComputer.filterAppAccess(uid, callingUid); } + private int[] getVisibilityAllowList(@NonNull String packageName, int userId) { + synchronized (mLock) { + final PackageSetting ps = getPackageSettingInternal(packageName, Process.SYSTEM_UID); + if (ps == null) { + return null; + } + final SparseArray visibilityAllowList = mAppsFilter.getVisibilityAllowList(ps, + new int[]{userId}, mSettings.getPackagesLocked()); + return visibilityAllowList != null ? visibilityAllowList.get(userId) : null; + } + } + private class PackageManagerInternalImpl extends PackageManagerInternal { @Override public List getInstalledApplications(int flags, int userId, @@ -27213,6 +27225,11 @@ public class PackageManagerService extends IPackageManager.Stub return PackageManagerService.this.filterAppAccess(uid, callingUid); } + @Nullable + public int[] getVisibilityAllowList(@NonNull String packageName, int userId) { + return PackageManagerService.this.getVisibilityAllowList(packageName, userId); + } + @Override public AndroidPackage getPackage(String packageName) { return PackageManagerService.this.getPackage(packageName);