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

Commit 376af6ff authored by Rhed Jao's avatar Rhed Jao
Browse files

Fix cross user package visibility leakage for filterAppAccess API

- To fix apis which invoke the #filterAppAccess leak the package
  existence information of other users, this CL returns true if
  the target package is not installed under the given user id.

- Add an extra boolean parameter to the #filterAppAccess API for
  the LauncherApp module to not filter the uninstalled package
  when monitoring package changes events.

- Correct wrong user id usages of the filterAppAccess API in
  some modules.

Bug: 229684723
Test: atest android.content.pm.cts.PackageManagerTest
Test: atest android.appenumeration.cts.AppEnumerationTests
Test: atest android.appwidget.cts.AppWidgetTest
Test: atest com.android.cts.devicepolicy.ManagedProfileCrossProfileTest
Test: atest com.android.cts.devicepolicy.LauncherAppsProfileTest
Test: atest android.devicepolicy.cts.LauncherAppsTests
Change-Id: I3cced4668d1cc4488665c928e4cbe4e194c249cf
parent d7a58241
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1695,7 +1695,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
                        && mSecurityPolicy.isProviderInCallerOrInProfileAndWhitelListed(
                        providerPackageName, providerProfileId)
                        && !mPackageManagerInternal.filterAppAccess(providerPackageName, callingUid,
                        userId)) {
                        profileId)) {
                    result.add(cloneIfLocalBinder(info));
                }
            }
+24 −3
Original line number Diff line number Diff line
@@ -737,28 +737,49 @@ public abstract class PackageManagerInternal {
    public abstract @Nullable String getInstantAppPackageName(int uid);

    /**
     * Returns whether or not access to the application should be filtered.
     * Returns whether or not access to the application should be filtered. The access is not
     * allowed if the application is not installed under the given user.
     * <p>
     * Access may be limited based upon whether the calling or target applications
     * are instant applications.
     *
     * @see #canAccessInstantApps
     *
     * @param pkg The package to be accessed.
     * @param callingUid The uid that attempts to access the package.
     * @param userId The user id where the package resides.
     */
    public abstract boolean filterAppAccess(
            @NonNull AndroidPackage pkg, int callingUid, int userId);

    /**
     * Returns whether or not access to the application should be filtered. The access is not
     * allowed if the application is not installed under the given user.
     *
     * @see #filterAppAccess(AndroidPackage, int, int)
     */
    public boolean filterAppAccess(@NonNull String packageName, int callingUid, int userId) {
        return filterAppAccess(packageName, callingUid, userId, true /* filterUninstalled */);
    }

    /**
     * Returns whether or not access to the application should be filtered.
     *
     * @param packageName The package to be accessed.
     * @param callingUid The uid that attempts to access the package.
     * @param userId The user id where the package resides.
     * @param filterUninstalled Set to true to filter the access if the package is not installed
     *                        under the given user.
     * @see #filterAppAccess(AndroidPackage, int, int)
     */
    public abstract boolean filterAppAccess(
            @NonNull String packageName, int callingUid, int userId);
            @NonNull String packageName, int callingUid, int userId, boolean filterUninstalled);

    /**
     * Returns whether or not access to the application which belongs to the given UID should be
     * filtered. If the UID is part of a shared user ID, return {@code true} if all applications
     * belong to the shared user ID should be filtered.
     * belong to the shared user ID should be filtered. The access is not allowed if the uid does
     * not exist in the device.
     *
     * @see #filterAppAccess(AndroidPackage, int, int)
     */
+2 −1
Original line number Diff line number Diff line
@@ -305,7 +305,8 @@ public interface Computer extends PackageDataSnapshot {
    SigningDetails getSigningDetails(@NonNull String packageName);
    SigningDetails getSigningDetails(int uid);
    boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId);
    boolean filterAppAccess(String packageName, int callingUid, int userId);
    boolean filterAppAccess(String packageName, int callingUid, int userId,
            boolean filterUninstalled);
    boolean filterAppAccess(int uid, int callingUid);
    void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState);
    PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityInternal(
+12 −11
Original line number Diff line number Diff line
@@ -3162,30 +3162,31 @@ public class ComputerEngine implements Computer {

    public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
        PackageStateInternal ps = getPackageStateInternal(pkg.getPackageName());
        return shouldFilterApplication(ps, callingUid,
                userId);
        return shouldFilterApplicationIncludingUninstalled(ps, callingUid, userId);
    }

    public boolean filterAppAccess(String packageName, int callingUid, int userId) {
    public boolean filterAppAccess(String packageName, int callingUid, int userId,
            boolean filterUninstalled) {
        PackageStateInternal ps = getPackageStateInternal(packageName);
        return shouldFilterApplication(ps, callingUid,
                userId);
        return shouldFilterApplication(
                ps, callingUid, null /* component */, TYPE_UNKNOWN, userId, filterUninstalled);
    }

    public boolean filterAppAccess(int uid, int callingUid) {
        final int userId = UserHandle.getUserId(uid);
        final int appId = UserHandle.getAppId(uid);
        final Object setting = mSettings.getSettingBase(appId);

        if (setting == null) {
            return true;
        }
        if (setting instanceof SharedUserSetting) {
            return shouldFilterApplication(
            return shouldFilterApplicationIncludingUninstalled(
                    (SharedUserSetting) setting, callingUid, userId);
        } else if (setting == null
                || setting instanceof PackageStateInternal) {
            return shouldFilterApplication(
        } else if (setting instanceof PackageStateInternal) {
            return shouldFilterApplicationIncludingUninstalled(
                    (PackageStateInternal) setting, callingUid, userId);
        }
        return false;
        return true;
    }

    public void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
+2 −1
Original line number Diff line number Diff line
@@ -89,7 +89,8 @@ public final class DomainVerificationConnection implements DomainVerificationSer

    @Override
    public boolean filterAppAccess(String packageName, int callingUid, int userId) {
        return mPm.snapshotComputer().filterAppAccess(packageName, callingUid, userId);
        return mPm.snapshotComputer().filterAppAccess(
                packageName, callingUid, userId, true /* filterUninstalled */);
    }

    @Override
Loading