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

Commit 8378ff94 authored by Christophe Pinelli's avatar Christophe Pinelli Committed by Android (Google) Code Review
Browse files

Merge "Revert^2 "Verify that the component is exported""

parents bcd00b31 f3ef712a
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -4216,13 +4216,23 @@ public class ActivityManager {
        }
    }*/

    /** @hide
     * Determines whether the given UID can access unexported components
     * @param uid the calling UID
     * @return true if the calling UID is ROOT or SYSTEM
     */
    public static boolean canAccessUnexportedComponents(int uid) {
        final int appId = UserHandle.getAppId(uid);
        return (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID);
    }

    /** @hide */
    @UnsupportedAppUsage
    public static int checkComponentPermission(String permission, int uid,
            int owningUid, boolean exported) {
        // Root, system server get to do everything.
        final int appId = UserHandle.getAppId(uid);
        if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
        if (canAccessUnexportedComponents(uid)) {
            return PackageManager.PERMISSION_GRANTED;
        }
        // Isolated processes don't get any permissions.
+8 −0
Original line number Diff line number Diff line
@@ -576,6 +576,14 @@ public abstract class PackageManagerInternal {
            @PrivateResolveFlags long privateResolveFlags, int userId, boolean resolveForStart,
            int filterCallingUid);

    /**
     * Resolves an exported activity intent, allowing instant apps to be resolved.
     */
    public abstract ResolveInfo resolveIntentExported(Intent intent, String resolvedType,
            @PackageManager.ResolveInfoFlagsBits long flags,
            @PrivateResolveFlags long privateResolveFlags, int userId, boolean resolveForStart,
            int filterCallingUid);

    /**
    * Resolves a service intent, allowing instant apps to be resolved.
    */
+68 −0
Original line number Diff line number Diff line
@@ -215,6 +215,7 @@ import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetManagerInternal;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledAfter;
import android.content.AttributionSource;
import android.content.AutofillOptions;
import android.content.BroadcastReceiver;
@@ -584,6 +585,17 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Disabled
    private static final long DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED = 161145287L;
    /**
     * Apps targeting Android U and above will need to export components in order to invoke them
     * through implicit intents.
     *
     * If a component is not exported and invoked, it will be removed from the list of receivers.
     * This applies specifically to activities and broadcasts.
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public static final long IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS = 229362273;
    /**
     * The maximum number of bytes that {@link #setProcessStateSummary} accepts.
     *
@@ -12378,6 +12390,58 @@ public class ActivityManagerService extends IActivityManager.Stub
        return false;
    }
    /**
     * Filters out non-exported components in a given list of broadcast filters
     * @param intent the original intent
     * @param callingUid the calling UID
     * @param query the list of broadcast filters
     * @param platformCompat the instance of platform compat
     */
    private static void filterNonExportedComponents(Intent intent, int callingUid,
            List query, PlatformCompat platformCompat, String callerPackage) {
        if (query == null
                || intent.getPackage() != null
                || intent.getComponent() != null
                || ActivityManager.canAccessUnexportedComponents(callingUid)) {
            return;
        }
        for (int i = query.size() - 1; i >= 0; i--) {
            String componentInfo;
            ResolveInfo resolveInfo;
            BroadcastFilter broadcastFilter;
            if (query.get(i) instanceof ResolveInfo) {
                resolveInfo = (ResolveInfo) query.get(i);
                if (resolveInfo.getComponentInfo().exported) {
                    continue;
                }
                componentInfo = resolveInfo.getComponentInfo()
                        .getComponentName().flattenToShortString();
            } else if (query.get(i) instanceof BroadcastFilter) {
                broadcastFilter = (BroadcastFilter) query.get(i);
                if (broadcastFilter.exported) {
                    continue;
                }
                componentInfo = broadcastFilter.packageName;
            } else {
                continue;
            }
            if (!platformCompat.isChangeEnabledByUid(
                    IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS, callingUid)) {
                Slog.w(TAG, "Non-exported component not filtered out "
                        + "(will be filtered out once the app targets U+)- intent: "
                        + intent.getAction() + ", component: "
                        + componentInfo + ", sender: "
                        + callerPackage);
                return;
            }
            Slog.w(TAG, "Non-exported component filtered out - intent: "
                    + intent.getAction() + ", component: "
                    + componentInfo + ", sender: "
                    + callerPackage);
            query.remove(i);
        }
    }
    /**
     * Main code for cleaning up a process when it has gone away.  This is
     * called both as a result of the process dying, or directly when stopping
@@ -14217,6 +14281,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
        }
        filterNonExportedComponents(intent, callingUid, registeredReceivers,
                mPlatformCompat, callerPackage);
        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
        if (!ordered && NR > 0) {
            // If we are not serializing this broadcast, then send the
@@ -14319,6 +14385,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        if ((receivers != null && receivers.size() > 0)
                || resultTo != null) {
            BroadcastQueue queue = broadcastQueueForIntent(intent);
            filterNonExportedComponents(intent, callingUid, receivers,
                    mPlatformCompat, callerPackage);
            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
                    callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
                    requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions,
+14 −0
Original line number Diff line number Diff line
@@ -465,6 +465,20 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal {
                filterCallingUid);
    }

    /**
     * @deprecated similar to {@link resolveIntent} but limits the matches to exported components.
     */
    @Override
    @Deprecated
    public final ResolveInfo resolveIntentExported(Intent intent, String resolvedType,
            @PackageManager.ResolveInfoFlagsBits long flags,
            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
            boolean resolveForStart, int filterCallingUid) {
        return getResolveIntentHelper().resolveIntentInternal(snapshot(),
                intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
                filterCallingUid, true);
    }

    @Override
    @Deprecated
    public final ResolveInfo resolveService(Intent intent, String resolvedType,
+51 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.util.Slog;

import com.android.internal.app.ResolverActivity;
import com.android.internal.util.ArrayUtils;
import com.android.server.am.ActivityManagerService;
import com.android.server.compat.PlatformCompat;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
@@ -100,6 +101,38 @@ final class ResolveIntentHelper {
        mInstantAppInstallerActivitySupplier = instantAppInstallerActivitySupplier;
    }

    private static void filterNonExportedComponents(Intent intent, int filterCallingUid,
            List<ResolveInfo> query, PlatformCompat platformCompat, Computer computer) {
        if (query == null
                || intent.getPackage() != null
                || intent.getComponent() != null
                || ActivityManager.canAccessUnexportedComponents(filterCallingUid)) {
            return;
        }
        AndroidPackage caller = computer.getPackage(filterCallingUid);
        String callerPackage = caller == null ? "Not specified" : caller.getPackageName();
        for (int i = query.size() - 1; i >= 0; i--) {
            if (!query.get(i).getComponentInfo().exported) {
                if (!platformCompat.isChangeEnabledByUid(
                        ActivityManagerService.IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS,
                        filterCallingUid)) {
                    Slog.w(TAG, "Non-exported component not filtered out "
                            + "(will be filtered out once the app targets U+)- intent: "
                            + intent.getAction() + ", component: "
                            + query.get(i).getComponentInfo()
                            .getComponentName().flattenToShortString()
                            + ", starter: " + callerPackage);
                    return;
                }
                Slog.w(TAG, "Non-exported component filtered out - intent: "
                        + intent.getAction() + ", component: "
                        + query.get(i).getComponentInfo().getComponentName().flattenToShortString()
                        + ", starter: " + callerPackage);
                query.remove(i);
            }
        }
    }

    /**
     * Normally instant apps can only be resolved when they're visible to the caller.
     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
@@ -109,6 +142,20 @@ final class ResolveIntentHelper {
            @PackageManager.ResolveInfoFlagsBits long flags,
            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
            boolean resolveForStart, int filterCallingUid) {
        return resolveIntentInternal(computer, intent, resolvedType, flags,
                privateResolveFlags, userId, resolveForStart, filterCallingUid, false);
    }

    /**
     * Normally instant apps can only be resolved when they're visible to the caller.
     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
     * since we need to allow the system to start any installed application.
     * Allows picking exported components only.
     */
    public ResolveInfo resolveIntentInternal(Computer computer, Intent intent, String resolvedType,
            @PackageManager.ResolveInfoFlagsBits long flags,
            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
            boolean resolveForStart, int filterCallingUid, boolean exportedComponentsOnly) {
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");

@@ -124,6 +171,10 @@ final class ResolveIntentHelper {
            final List<ResolveInfo> query = computer.queryIntentActivitiesInternal(intent,
                    resolvedType, flags, privateResolveFlags, filterCallingUid, userId,
                    resolveForStart, true /*allowDynamicSplits*/);
            if (exportedComponentsOnly) {
                filterNonExportedComponents(intent, filterCallingUid, query,
                        mPlatformCompat, computer);
            }
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

            final boolean queryMayBeFiltered =
Loading