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

Commit dd6dd3b1 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Apply AttributionSource during Intent delivery.

There are some Parcelables which offer to perform Binder calls, and
when these are delivered via Intent extras they fallback to
ActivityThread.currentAttributionSource(), instead of being tagged
based on the relevant app component.

This change begins using Intent.prepareToEnterProcess() as a hook to
fix-up AttributionSource when those extras finally land in the
destination process.  It uses the relevant AttributionSource based
on the Activity or Service the Intent is delivered to, which
developers have control over via AppComponentFactory.

In the case of <receiver> manifest elements, this change applies the
first android:attributionTags value to the Context used for that
BroadcastReceiver.

Bug: 187097694
Test: atest AttributionTest
Change-Id: I8f5197db7e8d7277d34f0ef2bb90bfdf1871186a
parent 3bf189f7
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -3509,7 +3509,8 @@ public final class ActivityThread extends ClientTransactionHandler
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo));
            r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                    activity.getAttributionSource());
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
@@ -3801,7 +3802,8 @@ 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(isProtectedComponent(r.activityInfo));
            intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                    r.activity.getAttributionSource());
            r.activity.mFragments.noteStateNotSaved();
            mInstrumentation.callActivityOnNewIntent(r.activity, intent);
        }
@@ -4241,10 +4243,15 @@ public final class ActivityThread extends ClientTransactionHandler
            if (data.info.splitName != null) {
                context = (ContextImpl) context.createContextForSplit(data.info.splitName);
            }
            if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
                final String attributionTag = data.info.attributionTags[0];
                context = (ContextImpl) context.createAttributionContext(attributionTag);
            }
            java.lang.ClassLoader cl = context.getClassLoader();
            data.intent.setExtrasClassLoader(cl);
            data.intent.prepareToEnterProcess(
                    isProtectedComponent(data.info) || isProtectedBroadcast(data.intent));
                    isProtectedComponent(data.info) || isProtectedBroadcast(data.intent),
                    context.getAttributionSource());
            data.setExtrasClassLoader(cl);
            receiver = packageInfo.getAppFactory()
                    .instantiateReceiver(cl, data.info.name, data.intent);
@@ -4469,7 +4476,8 @@ public final class ActivityThread extends ClientTransactionHandler
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess(isProtectedComponent(createData.info));
                data.intent.prepareToEnterProcess(isProtectedComponent(createData.info),
                        s.getAttributionSource());
                try {
                    if (!data.rebind) {
                        IBinder binder = s.onBind(data.intent);
@@ -4499,7 +4507,8 @@ public final class ActivityThread extends ClientTransactionHandler
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess(isProtectedComponent(createData.info));
                data.intent.prepareToEnterProcess(isProtectedComponent(createData.info),
                        s.getAttributionSource());
                boolean doRebind = s.onUnbind(data.intent);
                try {
                    if (doRebind) {
@@ -4588,7 +4597,8 @@ public final class ActivityThread extends ClientTransactionHandler
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess(isProtectedComponent(createData.info));
                    data.args.prepareToEnterProcess(isProtectedComponent(createData.info),
                            s.getAttributionSource());
                }
                int res;
                if (!data.taskRemoved) {
@@ -5241,7 +5251,8 @@ public final class ActivityThread extends ClientTransactionHandler
            try {
                if (ri.mData != null) {
                    ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
                    ri.mData.prepareToEnterProcess(isProtectedComponent(r.activityInfo));
                    ri.mData.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                            r.activity.getAttributionSource());
                }
                if (DEBUG_RESULTS) Slog.v(TAG,
                        "Delivering result to activity " + r + " : " + ri);
+2 −1
Original line number Diff line number Diff line
@@ -1774,7 +1774,8 @@ class ContextImpl extends Context {
                intent.setExtrasClassLoader(getClassLoader());
                // TODO: determine at registration time if caller is
                // protecting themselves with signature permission
                intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent));
                intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
                        getAttributionSource());
            }
            return intent;
        } catch (RemoteException e) {
+2 −1
Original line number Diff line number Diff line
@@ -1651,7 +1651,8 @@ public final class LoadedApk {
                        intent.setExtrasClassLoader(cl);
                        // TODO: determine at registration time if caller is
                        // protecting themselves with signature permission
                        intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent));
                        intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
                                mContext.getAttributionSource());
                        setExtrasClassLoader(cl);
                        receiver.setPendingResult(this);
                        receiver.onReceive(mContext, intent);
+5 −0
Original line number Diff line number Diff line
@@ -1190,6 +1190,11 @@ public final class BluetoothDevice implements Parcelable {
        return devices;
    }

    /** {@hide} */
    public void prepareToEnterProcess(AttributionSource attributionSource) {
        setAttributionSource(attributionSource);
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (o instanceof BluetoothDevice) {
+2 −2
Original line number Diff line number Diff line
@@ -1034,14 +1034,14 @@ public class ClipData implements Parcelable {
    }

    /** {@hide} */
    public void prepareToEnterProcess() {
    public void prepareToEnterProcess(AttributionSource source) {
        final int size = mItems.size();
        for (int i = 0; i < size; i++) {
            final Item item = mItems.get(i);
            if (item.mIntent != null) {
                // 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);
                item.mIntent.prepareToEnterProcess(false, source);
            }
        }
    }
Loading