Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f7e68c0 authored by Rhed Jao's avatar Rhed Jao
Browse files

Fix cross user package visibility leakage for getAppOpPermissionPackages

To fix cross user package visibility leakage, this CL filters out
packages that aren't installed in the calling user before the API
returns results to the caller.

Also adding a user id parameter to the API for the system modules to
specify the correct user id when querying the appop permission packages.

NoNonSdkCheck: Keep @UnsupportedAppUsage for new signature api
Bug: 229684723
Test: atest CrossUserPackageVisibilityTests
Change-Id: I9d3de91b0195d3396d2737673cb23ef899e23467
parent 6d8dfd00
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -110,7 +110,6 @@ Landroid/content/pm/IPackageInstallObserver2$Stub;-><init>()V
Landroid/content/pm/IPackageInstallObserver2$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageInstallObserver2;
Landroid/content/pm/IPackageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageManager$Stub$Proxy;->checkUidPermission(Ljava/lang/String;I)I
Landroid/content/pm/IPackageManager$Stub$Proxy;->getAppOpPermissionPackages(Ljava/lang/String;)[Ljava/lang/String;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstallLocation()I
Landroid/content/pm/IPackageManager$Stub$Proxy;->getLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;I)Landroid/content/pm/ResolveInfo;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
+1 −1
Original line number Diff line number Diff line
@@ -746,7 +746,7 @@ interface IPackageManager {
    // We need to keep these in IPackageManager for app compatibility
    //------------------------------------------------------------------------
    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
    String[] getAppOpPermissionPackages(String permissionName);
    String[] getAppOpPermissionPackages(String permissionName, int userId);

    @UnsupportedAppUsage
    PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
+1 −1
Original line number Diff line number Diff line
@@ -425,7 +425,7 @@ public interface Computer extends PackageDataSnapshot {
    boolean isUidPrivileged(int uid);

    @NonNull
    String[] getAppOpPermissionPackages(@NonNull String permissionName);
    String[] getAppOpPermissionPackages(@NonNull String permissionName, int userId);

    @NonNull
    ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(@NonNull String[] permissions,
+7 −8
Original line number Diff line number Diff line
@@ -4699,22 +4699,21 @@ public class ComputerEngine implements Computer {
    // NOTE: Can't remove due to unsupported app usage
    @NonNull
    @Override
    public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
        if (permissionName == null) {
            return EmptyArray.STRING;
        }
    public String[] getAppOpPermissionPackages(@NonNull String permissionName, int userId) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
                false /* checkShell */, "getAppOpPermissionPackages");
        if (permissionName == null || getInstantAppPackageName(callingUid) != null
                || !mUserManager.exists(userId)) {
            return EmptyArray.STRING;
        }
        final int callingUserId = UserHandle.getUserId(callingUid);

        final ArraySet<String> packageNames = new ArraySet(
                mPermissionManager.getAppOpPermissionPackages(permissionName));
        for (int i = packageNames.size() - 1; i >= 0; i--) {
            final String packageName = packageNames.valueAt(i);
            if (!shouldFilterApplication(mSettings.getPackage(packageName), callingUid,
                    callingUserId)) {
            if (!shouldFilterApplicationIncludingUninstalled(
                    mSettings.getPackage(packageName), callingUid, userId)) {
                continue;
            }
            packageNames.removeAt(i);
+8 −6
Original line number Diff line number Diff line
@@ -265,8 +265,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
    }

    private boolean canRequestInteractAcrossProfilesUnchecked(String packageName) {
        final int callingUserId = mInjector.getCallingUserId();
        final int[] enabledProfileIds =
                mInjector.getUserManager().getEnabledProfileIds(mInjector.getCallingUserId());
                mInjector.getUserManager().getEnabledProfileIds(callingUserId);
        if (enabledProfileIds.length < 2) {
            return false;
        }
@@ -274,13 +275,14 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
            return false;
        }
        return hasRequestedAppOpPermission(
                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName);
                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName,
                callingUserId);
    }

    private boolean hasRequestedAppOpPermission(String permission, String packageName) {
    private boolean hasRequestedAppOpPermission(String permission, String packageName, int userId) {
        try {
            String[] packages =
                    mInjector.getIPackageManager().getAppOpPermissionPackages(permission);
                    mInjector.getIPackageManager().getAppOpPermissionPackages(permission, userId);
            return ArrayUtils.contains(packages, packageName);
        } catch (RemoteException exc) {
            Slog.e(TAG, "PackageManager dead. Cannot get permission info");
@@ -604,7 +606,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
            return false;
        }
        if (!hasRequestedAppOpPermission(
                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)) {
                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName, userId)) {
            return false;
        }
        return isCrossProfilePackageAllowlisted(packageName);
@@ -627,7 +629,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
            return false;
        }
        if (!hasRequestedAppOpPermission(
                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)) {
                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName, userId)) {
            return false;
        }
        return !isPlatformSignedAppWithNonUserConfigurablePermission(packageName, profileIds);
Loading