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

Commit af1fafe9 authored by Michael Groover's avatar Michael Groover Committed by Android (Google) Code Review
Browse files

Merge "Add StrictMode check for unsafe intent launching"

parents 85712bdf 6728d4f9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -31281,6 +31281,7 @@ package android.os {
    method @NonNull public android.os.StrictMode.VmPolicy.Builder detectLeakedRegistrationObjects();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder detectNonSdkApiUsage();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder detectUnsafeIntentLaunch();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder detectUntaggedSockets();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyDeath();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnCleartextNetwork();
@@ -31289,6 +31290,7 @@ package android.os {
    method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.StrictMode.OnVmViolationListener);
    method @NonNull public android.os.StrictMode.VmPolicy.Builder penaltyLog();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder permitNonSdkApiUsage();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder permitUnsafeIntentLaunch();
    method @NonNull public android.os.StrictMode.VmPolicy.Builder setClassInstanceLimit(Class, int);
  }
@@ -31815,6 +31817,9 @@ package android.os.strictmode {
  public final class UnbufferedIoViolation extends android.os.strictmode.Violation {
  }
  public final class UnsafeIntentLaunchViolation extends android.os.strictmode.Violation {
  }
  public final class UntaggedSocketViolation extends android.os.strictmode.Violation {
  }
+76 −7
Original line number Diff line number Diff line
@@ -64,12 +64,14 @@ import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.IPackageManager;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ProviderInfoList;
import android.content.pm.ServiceInfo;
@@ -346,6 +348,7 @@ public final class ActivityThread extends ClientTransactionHandler {
    private int mPendingProcessState = PROCESS_STATE_UNKNOWN;
    ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>();
    private int mLastSessionId;
    final ArrayMap<IBinder, CreateServiceData> mServicesData = new ArrayMap<>();
    @UnsupportedAppUsage
    final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
    @UnsupportedAppUsage
@@ -3412,7 +3415,7 @@ public final class ActivityThread extends ClientTransactionHandler {
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo));
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
@@ -3717,7 +3720,7 @@ public final class ActivityThread extends ClientTransactionHandler {
        for (int i=0; i<N; i++) {
            ReferrerIntent intent = intents.get(i);
            intent.setExtrasClassLoader(r.activity.getClassLoader());
            intent.prepareToEnterProcess();
            intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo));
            r.activity.mFragments.noteStateNotSaved();
            mInstrumentation.callActivityOnNewIntent(r.activity, intent);
        }
@@ -4052,7 +4055,8 @@ public final class ActivityThread extends ClientTransactionHandler {
            }
            java.lang.ClassLoader cl = context.getClassLoader();
            data.intent.setExtrasClassLoader(cl);
            data.intent.prepareToEnterProcess();
            data.intent.prepareToEnterProcess(
                    isProtectedComponent(data.info) || isProtectedBroadcast(data.intent));
            data.setExtrasClassLoader(cl);
            receiver = packageInfo.getAppFactory()
                    .instantiateReceiver(cl, data.info.name, data.intent);
@@ -4249,6 +4253,7 @@ public final class ActivityThread extends ClientTransactionHandler {
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            service.onCreate();
            mServicesData.put(data.token, data);
            mServices.put(data.token, service);
            try {
                ActivityManager.getService().serviceDoneExecuting(
@@ -4266,13 +4271,14 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    private void handleBindService(BindServiceData data) {
        CreateServiceData createData = mServicesData.get(data.token);
        Service s = mServices.get(data.token);
        if (DEBUG_SERVICE)
            Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
                data.intent.prepareToEnterProcess(isProtectedComponent(createData.info));
                try {
                    if (!data.rebind) {
                        IBinder binder = s.onBind(data.intent);
@@ -4297,11 +4303,12 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    private void handleUnbindService(BindServiceData data) {
        CreateServiceData createData = mServicesData.get(data.token);
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
                data.intent.prepareToEnterProcess(isProtectedComponent(createData.info));
                boolean doRebind = s.onUnbind(data.intent);
                try {
                    if (doRebind) {
@@ -4373,12 +4380,13 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    private void handleServiceArgs(ServiceArgsData data) {
        CreateServiceData createData = mServicesData.get(data.token);
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                    data.args.prepareToEnterProcess(isProtectedComponent(createData.info));
                }
                int res;
                if (!data.taskRemoved) {
@@ -4407,6 +4415,7 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    private void handleStopService(IBinder token) {
        mServicesData.remove(token);
        Service s = mServices.remove(token);
        if (s != null) {
            try {
@@ -5026,7 +5035,7 @@ public final class ActivityThread extends ClientTransactionHandler {
            try {
                if (ri.mData != null) {
                    ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
                    ri.mData.prepareToEnterProcess();
                    ri.mData.prepareToEnterProcess(isProtectedComponent(r.activityInfo));
                }
                if (DEBUG_RESULTS) Slog.v(TAG,
                        "Delivering result to activity " + r + " : " + ri);
@@ -7739,6 +7748,66 @@ public final class ActivityThread extends ClientTransactionHandler {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }

    /**
     * Returns whether the provided {@link ActivityInfo} {@code ai} is a protected component.
     *
     * @see #isProtectedComponent(ComponentInfo, String)
     */
    public static boolean isProtectedComponent(@NonNull ActivityInfo ai) {
        return isProtectedComponent(ai, ai.permission);
    }

    /**
     * Returns whether the provided {@link ServiceInfo} {@code si} is a protected component.
     *
     * @see #isProtectedComponent(ComponentInfo, String)
     */
    public static boolean isProtectedComponent(@NonNull ServiceInfo si) {
        return isProtectedComponent(si, si.permission);
    }

    /**
     * Returns whether the provided {@link ComponentInfo} {@code ci} with the specified {@code
     * permission} is a protected component.
     *
     * <p>A component is protected if it is not exported, or if the specified {@code permission} is
     * a signature permission.
     */
    private static boolean isProtectedComponent(@NonNull ComponentInfo ci,
            @Nullable String permission) {
        // Bail early when this process isn't looking for violations
        if (!StrictMode.vmUnsafeIntentLaunchEnabled()) return false;

        // TODO: consider optimizing by having AMS pre-calculate this value
        if (!ci.exported) {
            return true;
        }
        if (permission != null) {
            try {
                PermissionInfo pi = getPermissionManager().getPermissionInfo(permission,
                        currentOpPackageName(), 0);
                return (pi != null) && pi.getProtection() == PermissionInfo.PROTECTION_SIGNATURE;
            } catch (RemoteException ignored) {
            }
        }
        return false;
    }

    /**
     * Returns whether the action within the provided {@code intent} is a protected broadcast.
     */
    public static boolean isProtectedBroadcast(@NonNull Intent intent) {
        // Bail early when this process isn't looking for violations
        if (!StrictMode.vmUnsafeIntentLaunchEnabled()) return false;

        // TODO: consider optimizing by having AMS pre-calculate this value
        try {
            return getPackageManager().isProtectedBroadcast(intent.getAction());
        } catch (RemoteException ignored) {
        }
        return false;
    }

    // ------------------ Regular JNI ------------------------
    private native void nPurgePendingResources();
    private native void nDumpGraphicsInfo(FileDescriptor fd);
+3 −1
Original line number Diff line number Diff line
@@ -1670,7 +1670,9 @@ class ContextImpl extends Context {
                    flags);
            if (intent != null) {
                intent.setExtrasClassLoader(getClassLoader());
                intent.prepareToEnterProcess();
                // TODO: determine at registration time if caller is
                // protecting themselves with signature permission
                intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent));
            }
            return intent;
        } catch (RemoteException e) {
+3 −1
Original line number Diff line number Diff line
@@ -1617,7 +1617,9 @@ public final class LoadedApk {
                    try {
                        ClassLoader cl = mReceiver.getClass().getClassLoader();
                        intent.setExtrasClassLoader(cl);
                        intent.prepareToEnterProcess();
                        // TODO: determine at registration time if caller is
                        // protecting themselves with signature permission
                        intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent));
                        setExtrasClassLoader(cl);
                        receiver.setPendingResult(this);
                        receiver.onReceive(mContext, intent);
+3 −1
Original line number Diff line number Diff line
@@ -1008,7 +1008,9 @@ public class ClipData implements Parcelable {
        for (int i = 0; i < size; i++) {
            final Item item = mItems.get(i);
            if (item.mIntent != null) {
                item.mIntent.prepareToEnterProcess();
                // We can't recursively claim that this data is from a protected
                // component, since it may have been filled in by a malicious app
                item.mIntent.prepareToEnterProcess(false);
            }
        }
    }
Loading