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

Commit c13b9153 authored by Rhed Jao's avatar Rhed Jao
Browse files

Add filtering uninstalled package flag to the shouldFilterApplication

A lot of APIs in PackageManager return different results between an
unknown package and the package that is uninstalled in the current
user. An app can detect package's existence via this side-channel
leakage.

To fix these issues, this CL adds an extra flag to the
shouldFilterApplication() to support filtering uninstalled package.
APIs with the vulnerability can enable the flag when they invoke
application access filtering. (The fixes for those APIs are separated
into other CLs.)

Bug: 214394643
Test: atest AppEnumerationTests
Change-Id: I2875765b631c247539955c1d5dc864798e54896c
parent 9fcc8c50
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -215,6 +215,9 @@ public interface Computer extends PackageDataSnapshot {
    boolean isInstantApp(String packageName, int userId);
    boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid);
    boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId);
    boolean shouldFilterApplication(@Nullable PackageStateInternal ps, int callingUid,
            @Nullable ComponentName component, @PackageManager.ComponentType int componentType,
            int userId, boolean filterUninstall);
    boolean shouldFilterApplication(@Nullable PackageStateInternal ps, int callingUid,
            @Nullable ComponentName component, @PackageManager.ComponentType int componentType,
            int userId);
@@ -222,6 +225,8 @@ public interface Computer extends PackageDataSnapshot {
            int userId);
    boolean shouldFilterApplication(@NonNull SharedUserSetting sus, int callingUid,
            int userId);
    boolean shouldFilterApplicationIncludingUninstalled(@Nullable PackageStateInternal ps,
            int callingUid, int userId);
    int checkUidPermission(String permName, int uid);
    int getPackageUidInternal(String packageName, long flags, int userId, int callingUid);
    long updateFlagsForApplication(long flags, int userId);
+31 −9
Original line number Diff line number Diff line
@@ -2675,7 +2675,7 @@ public class ComputerEngine implements Computer {
     */
    public final boolean shouldFilterApplication(@Nullable PackageStateInternal ps,
            int callingUid, @Nullable ComponentName component,
            @PackageManager.ComponentType int componentType, int userId) {
            @PackageManager.ComponentType int componentType, int userId, boolean filterUninstall) {
        if (Process.isSdkSandboxUid(callingUid)) {
            int clientAppUid = Process.getAppUidForSdkSandboxUid(callingUid);
            // SDK sandbox should be able to see it's client app
@@ -2689,9 +2689,11 @@ public class ComputerEngine implements Computer {
        }
        final String instantAppPkgName = getInstantAppPackageName(callingUid);
        final boolean callerIsInstantApp = instantAppPkgName != null;
        if (ps == null) {
            // pretend the application exists, but, needs to be filtered
            return callerIsInstantApp;
        if (ps == null
                || (filterUninstall && !ps.getUserStateOrDefault(userId).isInstalled())) {
            // If caller is instant app and ps is null, pretend the application exists,
            // but, needs to be filtered
            return (callerIsInstantApp || filterUninstall);
        }
        // if the target and caller are the same application, don't filter
        if (isCallerSameApp(ps.getPackageName(), callingUid)) {
@@ -2736,15 +2738,26 @@ public class ComputerEngine implements Computer {
    }

    /**
     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int)
     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int, boolean)
     */
    public final boolean shouldFilterApplication(@Nullable PackageStateInternal ps,
            int callingUid, @Nullable ComponentName component,
            @PackageManager.ComponentType int componentType, int userId) {
        return shouldFilterApplication(
                ps, callingUid, component, componentType, userId, false /* filterUninstall */);
    }

    /**
     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int, boolean)
     */
    public final boolean shouldFilterApplication(
            @Nullable PackageStateInternal ps, int callingUid, int userId) {
        return shouldFilterApplication(ps, callingUid, null, TYPE_UNKNOWN, userId);
        return shouldFilterApplication(
                ps, callingUid, null, TYPE_UNKNOWN, userId, false /* filterUninstall */);
    }

    /**
     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int)
     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int, boolean)
     */
    public final boolean shouldFilterApplication(@NonNull SharedUserSetting sus,
            int callingUid, int userId) {
@@ -2752,12 +2765,21 @@ public class ComputerEngine implements Computer {
        final ArraySet<PackageStateInternal> packageStates =
                (ArraySet<PackageStateInternal>) sus.getPackageStates();
        for (int index = packageStates.size() - 1; index >= 0 && filterApp; index--) {
            filterApp &= shouldFilterApplication(packageStates.valueAt(index),
                    callingUid, /* component */ null, TYPE_UNKNOWN, userId);
            filterApp &= shouldFilterApplication(packageStates.valueAt(index), callingUid,
                    null /* component */, TYPE_UNKNOWN, userId, false /* filterUninstall */);
        }
        return filterApp;
    }

    /**
     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int, boolean)
     */
    public final boolean shouldFilterApplicationIncludingUninstalled(
            @Nullable PackageStateInternal ps, int callingUid, int userId) {
        return shouldFilterApplication(
                ps, callingUid, null, TYPE_UNKNOWN, userId, true /* filterUninstall */);
    }

    /**
     * Verification statuses are ordered from the worse to the best, except for
     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
+2 −3
Original line number Diff line number Diff line
@@ -6617,9 +6617,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            @UserIdInt int userId) {
        PackageStateInternal packageState =
                computer.getPackageStateInternal(packageName, callingUid);
        if (packageState == null
                || computer.shouldFilterApplication(packageState, callingUid, userId)
                || !packageState.getUserStateOrDefault(userId).isInstalled()) {
        if (computer.shouldFilterApplicationIncludingUninstalled(
                packageState, callingUid, userId)) {
            return null;
        } else {
            return packageState;