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

Commit 8b1f9674 authored by John Wu's avatar John Wu
Browse files

Fix package visibility broadcast regression

Sending broadcasts are not restricted by the package visibility of the
calling package. This is achieved by clearing the Binder calling
identity in several top-level broadcast sending APIs.

ag/15315839 introduced intent filter matching enforcement, which
requires the real calling UID to be used for evaluation. This caused
regression in broadcast package visibility.

Test: manual
Bug: 230363029
Change-Id: I6bf34fe22aa9396786e3bbbfe64094474c34b6df
parent 41608ecf
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -334,10 +334,14 @@ public abstract class PackageManagerInternal {

    /**
     * Retrieve all receivers that can handle a broadcast of the given intent.
     * @param filterCallingUid The results will be filtered in the context of this UID instead
     *                         of the calling UID.
     * @param forSend true if the invocation is intended for sending broadcasts. The value
     *                of this parameter affects how packages are filtered.
     */
    public abstract List<ResolveInfo> queryIntentReceivers(Intent intent,
            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
            int filterCallingUid, int userId);
            int filterCallingUid, int userId, boolean forSend);

    /**
     * Retrieve all services that can be performed for the given intent.
+5 −4
Original line number Diff line number Diff line
@@ -13251,8 +13251,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
                continue;
            }
            List<ResolveInfo> newReceivers = mPackageManagerInt
                    .queryIntentReceivers(intent, resolvedType, pmFlags, callingUid, user);
            List<ResolveInfo> newReceivers = mPackageManagerInt.queryIntentReceivers(
                    intent, resolvedType, pmFlags, callingUid, user, true /* forSend */);
            if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
                // If this is not the system user, we need to check for
                // any receivers that should be filtered out.
@@ -13268,8 +13268,9 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (newReceivers != null) {
                for (int i = newReceivers.size() - 1; i >= 0; i--) {
                    final ResolveInfo ri = newReceivers.get(i);
                    final Resolution<ResolveInfo> resolution = mComponentAliasResolver
                            .resolveReceiver(intent, ri, resolvedType, pmFlags, user, callingUid);
                    final Resolution<ResolveInfo> resolution =
                            mComponentAliasResolver.resolveReceiver(intent, ri, resolvedType,
                                    pmFlags, user, callingUid, true /* forSend */);
                    if (resolution == null) {
                        // It was an alias, but the target was not found.
                        newReceivers.remove(i);
+3 −3
Original line number Diff line number Diff line
@@ -483,7 +483,7 @@ public class ComponentAliasResolver {
    @Nullable
    public Resolution<ResolveInfo> resolveReceiver(@NonNull Intent intent,
            @NonNull ResolveInfo receiver, @Nullable String resolvedType,
            int packageFlags, int userId, int callingUid) {
            int packageFlags, int userId, int callingUid, boolean forSend) {
        // Resolve this alias.
        final Resolution<ComponentName> resolution = resolveComponentAlias(() ->
                receiver.activityInfo.getComponentName());
@@ -506,8 +506,8 @@ public class ComponentAliasResolver {
        i.setPackage(null);
        i.setComponent(resolution.getTarget());

        List<ResolveInfo> resolved = pmi.queryIntentReceivers(i,
                resolvedType, packageFlags, callingUid, userId);
        List<ResolveInfo> resolved = pmi.queryIntentReceivers(
                i, resolvedType, packageFlags, callingUid, userId, forSend);
        if (resolved == null || resolved.size() == 0) {
            // Target component not found.
            Slog.w(TAG, "Alias target " + target.flattenToShortString() + " not found");
+3 −3
Original line number Diff line number Diff line
@@ -315,9 +315,9 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal {
    @Deprecated
    public final List<ResolveInfo> queryIntentReceivers(Intent intent,
            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
            int filterCallingUid, int userId) {
        return getResolveIntentHelper().queryIntentReceiversInternal(
                snapshot(), intent, resolvedType, flags, userId, filterCallingUid);
            int filterCallingUid, int userId, boolean forSend) {
        return getResolveIntentHelper().queryIntentReceiversInternal(snapshot(), intent,
                resolvedType, flags, userId, filterCallingUid, forSend);
    }

    @Override
+25 −9
Original line number Diff line number Diff line
@@ -306,16 +306,32 @@ final class ResolveIntentHelper {
        return new IntentSender(target);
    }

    // In this method, we have to know the actual calling UID, but in some cases Binder's
    // call identity is removed, so the UID has to be passed in explicitly.
    public @NonNull List<ResolveInfo> queryIntentReceiversInternal(Computer computer, Intent intent,
    /**
     * Retrieve all receivers that can handle a broadcast of the given intent.
     * @param queryingUid the results will be filtered in the context of this UID instead.
     */
    @NonNull
    public List<ResolveInfo> queryIntentReceiversInternal(Computer computer, Intent intent,
            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
            int queryingUid) {
        return queryIntentReceiversInternal(computer, intent, resolvedType, flags, userId,
                queryingUid, false);
    }

    /**
     * @see PackageManagerInternal#queryIntentReceivers(Intent, String, long, int, int, boolean)
     */
    @NonNull
    public List<ResolveInfo> queryIntentReceiversInternal(Computer computer, Intent intent,
            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
            int filterCallingUid) {
            int filterCallingUid, boolean forSend) {
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        computer.enforceCrossUserPermission(filterCallingUid, userId, false /*requireFullPermission*/,
                false /*checkShell*/, "query intent receivers");
        final String instantAppPkgName = computer.getInstantAppPackageName(filterCallingUid);
        flags = computer.updateFlagsForResolve(flags, userId, filterCallingUid,
        // The identity used to filter the receiver components
        final int queryingUid = forSend ? Process.SYSTEM_UID : filterCallingUid;
        computer.enforceCrossUserPermission(queryingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/, "query intent receivers");
        final String instantAppPkgName = computer.getInstantAppPackageName(queryingUid);
        flags = computer.updateFlagsForResolve(flags, userId, queryingUid,
                false /*includeInstantApps*/,
                computer.isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId,
                        resolvedType, flags));
@@ -397,7 +413,7 @@ final class ResolveIntentHelper {
                    list, true, originalIntent, resolvedType, filterCallingUid);
        }

        return computer.applyPostResolutionFilter(list, instantAppPkgName, false, filterCallingUid,
        return computer.applyPostResolutionFilter(list, instantAppPkgName, false, queryingUid,
                false, userId, intent);
    }