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

Commit a9c54142 authored by John Wu's avatar John Wu
Browse files

Add intent filter matching enforcement for logging

Implement the planned behavior change for V in udc-qpr to reach a larger
testing population.

1. Update matching logic to consider the category default only flag
2. Guard the feature with the intent sender instead of the receiver
3. The feature is still hardcoded as disable; only logging is enabled

Bug: 293560872
Test: atest PackageManagerTest#testEnforceIntentToMatchIntentFilter
Test: atest PackageManagerTest#testLegacyIntentFilterMatching
Change-Id: I6740aa315106440ced13d618b5cd71fc20ca92e9
parent f78cd538
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ public abstract class IntentResolver<F, R extends Object> {
     * Returns whether an intent matches the IntentFilter with a pre-resolved type.
     */
    public static boolean intentMatchesFilter(
            IntentFilter filter, Intent intent, String resolvedType) {
            IntentFilter filter, Intent intent, String resolvedType, boolean defaultOnly) {
        final boolean debug = localLOGV
                || ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);

@@ -94,9 +94,13 @@ public abstract class IntentResolver<F, R extends Object> {
            filter.dump(logPrinter, "  ");
        }

        final int match = filter.match(intent.getAction(), resolvedType, intent.getScheme(),
        int match = filter.match(intent.getAction(), resolvedType, intent.getScheme(),
                intent.getData(), intent.getCategories(), TAG);

        if (match >= 0 && defaultOnly && !filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
            match = IntentFilter.NO_MATCH_CATEGORY;
        }

        if (match >= 0) {
            if (debug) {
                Slog.v(TAG, "Filter matched!  match=0x" + Integer.toHexString(match));
+20 −10
Original line number Diff line number Diff line
@@ -150,16 +150,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
    public boolean isChangeEnabledByUid(long changeId, int uid) {
        super.isChangeEnabledByUid_enforcePermission();

        String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
        if (packages == null || packages.length == 0) {
            return mCompatConfig.defaultChangeIdValue(changeId);
        }
        boolean enabled = true;
        for (String packageName : packages) {
            enabled &= isChangeEnabledByPackageName(changeId, packageName,
                    UserHandle.getUserId(uid));
        }
        return enabled;
        return isChangeEnabledByUidInternal(changeId, uid);
    }

    /**
@@ -208,6 +199,25 @@ public class PlatformCompat extends IPlatformCompat.Stub {
        return false;
    }

    /**
     * Internal version of {@link #isChangeEnabledByUid(long, int)}.
     *
     * <p>Does not perform costly permission check.
     */
    public boolean isChangeEnabledByUidInternal(long changeId, int uid) {
        String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
        if (packages == null || packages.length == 0) {
            return mCompatConfig.defaultChangeIdValue(changeId);
        }
        boolean enabled = true;
        final int userId = UserHandle.getUserId(uid);
        for (String packageName : packages) {
            final var appInfo = getApplicationInfo(packageName, userId);
            enabled &= isChangeEnabledInternal(changeId, appInfo);
        }
        return enabled;
    }

    @Override
    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
    public void setOverrides(CompatibilityChangeConfig overrides, String packageName) {
+4 −4
Original line number Diff line number Diff line
@@ -580,7 +580,7 @@ public class ComputerEngine implements Computer {
                    list.add(ri);
                    PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
                            mInjector.getCompatibility(), mComponentResolver,
                            list, false, intent, resolvedType, filterCallingUid);
                            list, false, intent, resolvedType, flags, filterCallingUid);
                }
            }
        } else {
@@ -610,7 +610,7 @@ public class ComputerEngine implements Computer {
            // We also have to ensure all components match the original intent
            PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
                    mInjector.getCompatibility(), mComponentResolver,
                    list, false, originalIntent, resolvedType, filterCallingUid);
                    list, false, originalIntent, resolvedType, flags, filterCallingUid);
        }

        return skipPostResolution ? list : applyPostResolutionFilter(
@@ -699,7 +699,7 @@ public class ComputerEngine implements Computer {
                    list.add(ri);
                    PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
                            mInjector.getCompatibility(), mComponentResolver,
                            list, false, intent, resolvedType, callingUid);
                            list, false, intent, resolvedType, flags, callingUid);
                }
            }
        } else {
@@ -711,7 +711,7 @@ public class ComputerEngine implements Computer {
            // We also have to ensure all components match the original intent
            PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
                    mInjector.getCompatibility(), mComponentResolver,
                    list, false, originalIntent, resolvedType, callingUid);
                    list, false, originalIntent, resolvedType, flags, callingUid);
        }

        return list;
+21 −12
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
import android.compat.annotation.Overridable;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -69,6 +70,7 @@ import android.os.Environment;
import android.os.FileUtils;
import android.os.Process;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.incremental.IncrementalManager;
import android.os.incremental.IncrementalStorage;
import android.os.incremental.V4Signature;
@@ -180,8 +182,9 @@ public class PackageManagerServiceUtils {
    public @interface SharedUserIdJoinType {}

    /**
     * Components of apps targeting Android T and above will stop receiving intents from
     * external callers that do not match its declared intent filters.
     * Intents sent from apps targeting Android V and above will stop resolving to components with
     * non matching intent filters, even when explicitly setting a component name, unless the
     * target components are in the same app as the calling app.
     *
     * When an app registers an exported component in its manifest and adds an <intent-filter>,
     * the component can be started by any intent - even those that do not match the intent filter.
@@ -189,8 +192,9 @@ public class PackageManagerServiceUtils {
     * Without checking the intent when the component is started, in some circumstances this can
     * allow 3P apps to trigger internal-only functionality.
     */
    @Overridable
    @ChangeId
    @Disabled  /* Revert enforcement: b/274147456 */
    @Disabled  /* Enforcement reverted in T: b/274147456 */
    private static final long ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS = 161252188;

    /**
@@ -1187,19 +1191,27 @@ public class PackageManagerServiceUtils {
    public static void applyEnforceIntentFilterMatching(
            PlatformCompat compat, ComponentResolverApi resolver,
            List<ResolveInfo> resolveInfos, boolean isReceiver,
            Intent intent, String resolvedType, int filterCallingUid) {
            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
            int filterCallingUid) {
        if (DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.get()) return;

        // Do not enforce filter matching when the caller is system or root
        if (ActivityManager.canAccessUnexportedComponents(filterCallingUid)) return;

        final Printer logPrinter = DEBUG_INTENT_MATCHING
                ? new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM)
                : null;

        final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;

        final boolean enforce = compat.isChangeEnabledByUidInternal(
                ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS, filterCallingUid);

        for (int i = resolveInfos.size() - 1; i >= 0; --i) {
            final ComponentInfo info = resolveInfos.get(i).getComponentInfo();

            // Do not enforce filter matching when the caller is system, root, or the same app
            if (ActivityManager.checkComponentPermission(null, filterCallingUid,
                    info.applicationInfo.uid, false) == PackageManager.PERMISSION_GRANTED) {
            // Skip filter matching when the caller is targeting the same app
            if (UserHandle.isSameApp(filterCallingUid, info.applicationInfo.uid)) {
                continue;
            }

@@ -1221,14 +1233,11 @@ public class PackageManagerServiceUtils {
                continue;
            }

            // Only enforce filter matching if target app's target SDK >= T
            final boolean enforce = compat.isChangeEnabledInternal(
                    ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS, info.applicationInfo);

            boolean match = false;
            for (int j = 0, size = comp.getIntents().size(); j < size; ++j) {
                IntentFilter intentFilter = comp.getIntents().get(j).getIntentFilter();
                if (IntentResolver.intentMatchesFilter(intentFilter, intent, resolvedType)) {
                if (IntentResolver.intentMatchesFilter(
                        intentFilter, intent, resolvedType, defaultOnly)) {
                    match = true;
                    break;
                }
+2 −2
Original line number Diff line number Diff line
@@ -459,7 +459,7 @@ final class ResolveIntentHelper {
                    list.add(ri);
                    PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
                            mPlatformCompat, componentResolver, list, true, intent,
                            resolvedType, filterCallingUid);
                            resolvedType, flags, filterCallingUid);
                }
            }
        } else {
@@ -485,7 +485,7 @@ final class ResolveIntentHelper {
            // We also have to ensure all components match the original intent
            PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
                    mPlatformCompat, componentResolver,
                    list, true, originalIntent, resolvedType, filterCallingUid);
                    list, true, originalIntent, resolvedType, flags, filterCallingUid);
        }

        return computer.applyPostResolutionFilter(list, instantAppPkgName, false, queryingUid,