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

Commit 3e66b0ad authored by John Wu's avatar John Wu
Browse files

Add new unsafe intent usage strict mode violations

Trigger unsafe intent usage violation when null action intent or
mismatching intent is being used to launch a component.

Bug: 293560872
Test: atest CtsPackageContentTestCases:SaferIntentTest
Change-Id: Ie09862a1a608b9b40f1312cf21ef66261eb479ea
parent b3d20839
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1103,7 +1103,7 @@ public abstract class ActivityManagerInternal {
    /**
     * Trigger an unsafe intent usage strict mode violation.
     */
    public abstract void triggerUnsafeIntentStrictMode(int callingPid, Intent intent);
    public abstract void triggerUnsafeIntentStrictMode(int callingPid, int type, Intent intent);

    /**
     * Start a foreground service delegate.
+1 −1
Original line number Diff line number Diff line
@@ -24,5 +24,5 @@ import android.content.Intent;
 */
oneway interface IUnsafeIntentStrictModeCallback
{
    void onImplicitIntentMatchedInternalComponent(in Intent intent);
    void onUnsafeIntent(int type, in Intent intent);
}
+36 −20
Original line number Diff line number Diff line
@@ -17,6 +17,10 @@ package android.os;

import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;

import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH;
import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH;
import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH;

import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -2135,27 +2139,26 @@ public final class StrictMode {
        }
    }

    private static void registerIntentMatchingRestrictionCallback() {
        try {
            ActivityManager.getService().registerStrictModeCallback(
                    new UnsafeIntentStrictModeCallback());
        } catch (RemoteException e) {
            /*
            If exception is DeadObjectException it means system process is dead, so we can ignore
             */
            if (!(e instanceof DeadObjectException)) {
                Log.e(TAG, "RemoteException handling StrictMode violation", e);
            }
        }
    }

    private static final class UnsafeIntentStrictModeCallback
            extends IUnsafeIntentStrictModeCallback.Stub {
        @Override
        public void onImplicitIntentMatchedInternalComponent(Intent intent) {
        public void onUnsafeIntent(int type, Intent intent) {
            if (StrictMode.vmUnsafeIntentLaunchEnabled()) {
                StrictMode.onUnsafeIntentLaunch(intent,
                        "Launch of unsafe implicit intent: " + intent);
                StrictMode.onUnsafeIntentLaunch(type, intent);
            }
        }
    }

    /** Each process should only have one singleton callback */
    private static volatile UnsafeIntentStrictModeCallback sUnsafeIntentCallback;

    private static void registerIntentMatchingRestrictionCallback() {
        if (sUnsafeIntentCallback == null) {
            sUnsafeIntentCallback = new UnsafeIntentStrictModeCallback();
            try {
                ActivityManager.getService().registerStrictModeCallback(sUnsafeIntentCallback);
            } catch (RemoteException e) {
                // system_server should not throw
            }
        }
    }
@@ -2383,9 +2386,22 @@ public final class StrictMode {
        onVmPolicyViolation(new UnsafeIntentLaunchViolation(intent));
    }

    /** @hide */
    public static void onUnsafeIntentLaunch(Intent intent, String message) {
        onVmPolicyViolation(new UnsafeIntentLaunchViolation(intent, message));
    private static void onUnsafeIntentLaunch(int type, Intent intent) {
        String msg;
        switch (type) {
            case UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH:
                msg = "Launch of intent with null action: ";
                break;
            case UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH:
                msg = "Implicit intent matching internal non-exported component: ";
                break;
            case UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH:
                msg = "Intent mismatch target component intent filter: ";
                break;
            default:
                return;
        }
        onVmPolicyViolation(new UnsafeIntentLaunchViolation(intent, msg + intent));
    }

    /** Assume locked until we hear otherwise */
+15 −6
Original line number Diff line number Diff line
@@ -368,17 +368,17 @@ public abstract class PackageManagerInternal {
            Intent intent, @Nullable String resolvedType,
            @PackageManager.ResolveInfoFlagsBits long flags, int filterCallingUid, int userId);


    /**
     * 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, boolean forSend);
    public abstract List<ResolveInfo> queryIntentReceivers(
            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
            int filterCallingUid, int callingPid, int userId, boolean forSend);

    /**
     * Retrieve all services that can be performed for the given intent.
@@ -624,6 +624,15 @@ public abstract class PackageManagerInternal {
    public abstract ResolveInfo resolveService(Intent intent, String resolvedType,
            @PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid);


    /**
     * Resolves a service intent for start.
     */
    public abstract ResolveInfo resolveService(
            Intent intent, String resolvedType,
            @PackageManager.ResolveInfoFlagsBits long flags, int userId,
            int callingUid, int callingPid);

    /**
    * Resolves a content provider intent.
    */
+2 −2
Original line number Diff line number Diff line
@@ -4887,7 +4887,7 @@ public final class ActiveServices {
                }
                // TODO: come back and remove this assumption to triage all services
                ResolveInfo rInfo = mAm.getPackageManagerInternal().resolveService(service,
                        resolvedType, flags, userId, callingUid);
                        resolvedType, flags, userId, callingUid, callingPid);
                ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
                if (sInfo == null) {
                    Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId +
@@ -5007,7 +5007,7 @@ public final class ActiveServices {
                        try {
                            ResolveInfo rInfoForUserId0 =
                                    mAm.getPackageManagerInternal().resolveService(service,
                                            resolvedType, flags, userId, callingUid);
                                            resolvedType, flags, userId, callingUid, callingPid);
                            if (rInfoForUserId0 == null) {
                                Slog.w(TAG_SERVICE,
                                        "Unable to resolve service " + service + " U=" + userId
Loading