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

Commit f0efc783 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Check intent creatorToken" into main

parents ef97c455 d044cbb6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1328,7 +1328,8 @@ public abstract class ActivityManagerInternal {
     * Add a creator token for all embedded intents (stored as extra) of the given intent.
     *
     * @param intent The given intent
     * @param creatorPackage the package name of the creator app.
     * @hide
     */
    public abstract void addCreatorToken(Intent intent);
    public abstract void addCreatorToken(Intent intent, String creatorPackage);
}
+42 −3
Original line number Diff line number Diff line
@@ -888,6 +888,22 @@ public class Intent implements Parcelable, Cloneable {
    public static final String ACTION_ACTIVITY_RECOGNIZER =
            "android.intent.action.ACTIVITY_RECOGNIZER";
    /** @hide */
    public static void maybeMarkAsMissingCreatorToken(Object object) {
        if (object instanceof Intent intent) {
            maybeMarkAsMissingCreatorTokenInternal(intent);
        }
    }
    private static void maybeMarkAsMissingCreatorTokenInternal(Intent intent) {
        boolean isForeign = (intent.mLocalFlags & LOCAL_FLAG_FROM_PARCEL) != 0;
        boolean isWithoutTrustedCreatorToken =
                (intent.mLocalFlags & Intent.LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT) == 0;
        if (isForeign && isWithoutTrustedCreatorToken) {
            intent.addExtendedFlags(EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN);
        }
    }
    /**
     * Represents a shortcut/live folder icon resource.
     *
@@ -7684,10 +7700,8 @@ public class Intent implements Parcelable, Cloneable {
    /**
     * This flag indicates the creator token of this intent has been verified.
     *
     * @hide
     */
    public static final int LOCAL_FLAG_CREATOR_TOKEN_VERIFIED = 1 << 6;
    private static final int LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT = 1 << 6;
    /** @hide */
    @IntDef(flag = true, prefix = { "EXTENDED_FLAG_" }, value = {
@@ -12243,6 +12257,30 @@ public class Intent implements Parcelable, Cloneable {
        }
    }
    /** @hide */
    public void checkCreatorToken() {
        if (mExtras == null) return;
        if (mCreatorTokenInfo != null && mCreatorTokenInfo.mExtraIntentKeys != null) {
            for (String key : mCreatorTokenInfo.mExtraIntentKeys) {
                try {
                    Intent extraIntent = mExtras.getParcelable(key, Intent.class);
                    if (extraIntent == null) {
                        Log.w(TAG, "The key {" + key
                                + "} does not correspond to an intent in the bundle.");
                        continue;
                    }
                    extraIntent.mLocalFlags |= LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT;
                } catch (Exception e) {
                    Log.e(TAG, "Failed to validate creator token. key: " + key + ".", e);
                }
            }
        }
        // mark the bundle as intent extras after calls to getParcelable.
        // otherwise, the logic to mark missing token would run before
        // mark trusted creator token present.
        mExtras.setIsIntentExtra();
    }
    public void writeToParcel(Parcel out, int flags) {
        out.writeString8(mAction);
        Uri.writeToParcel(out, mData);
@@ -12730,6 +12768,7 @@ public class Intent implements Parcelable, Cloneable {
        }
        mLocalFlags |= localFlags;
        checkCreatorToken();
        // Special attribution fix-up logic for any BluetoothDevice extras
        // passed via Bluetooth intents
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Intent;
import android.util.ArrayMap;
import android.util.Log;
import android.util.MathUtils;
@@ -401,6 +402,9 @@ public class BaseBundle {
            synchronized (this) {
                object = unwrapLazyValueFromMapLocked(i, clazz, itemTypes);
            }
            if ((mFlags & Bundle.FLAG_VERIFY_TOKENS_PRESENT) != 0) {
                Intent.maybeMarkAsMissingCreatorToken(object);
            }
        }
        return (clazz != null) ? clazz.cast(object) : (T) object;
    }
+11 −0
Original line number Diff line number Diff line
@@ -62,6 +62,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
    @VisibleForTesting
    static final int FLAG_HAS_BINDERS = 1 << 12;

    /**
     * Indicates there may be intents with creator tokens contained in this bundle. When unparceled,
     * they should be verified if tokens are missing or invalid.
     */
    static final int FLAG_VERIFY_TOKENS_PRESENT = 1 << 13;


    /**
     * Status when the Bundle can <b>assert</b> that the underlying Parcel DOES NOT contain
@@ -274,6 +280,11 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
        return orig;
    }

    /** {@hide} */
    public void setIsIntentExtra() {
        mFlags |= FLAG_VERIFY_TOKENS_PRESENT;
    }

    /**
     * Mark if this Bundle is okay to "defuse." That is, it's okay for system
     * processes to ignore any {@link BadParcelableException} encountered when
+42 −30
Original line number Diff line number Diff line
@@ -5542,7 +5542,6 @@ public class ActivityManagerService extends IActivityManager.Stub
    public int sendIntentSender(IApplicationThread caller, IIntentSender target,
            IBinder allowlistToken, int code, Intent intent, String resolvedType,
            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
        addCreatorToken(intent);
        if (target instanceof PendingIntentRecord) {
            final PendingIntentRecord originalRecord = (PendingIntentRecord) target;
@@ -5584,7 +5583,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                intent = new Intent(Intent.ACTION_MAIN);
            }
            try {
                if (allowlistToken != null) {
                final int callingUid = Binder.getCallingUid();
                final String packageName;
                final long token = Binder.clearCallingIdentity();
@@ -5593,10 +5591,15 @@ public class ActivityManagerService extends IActivityManager.Stub
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
                if (allowlistToken != null) {
                    Slog.wtf(TAG, "Send a non-null allowlistToken to a non-PI target."
                            + " Calling package: " + packageName + "; intent: " + intent
                            + "; options: " + options);
                }
                addCreatorToken(intent, packageName);
                target.send(code, intent, resolvedType, null, null,
                        requiredPermission, options);
            } catch (RemoteException e) {
@@ -13628,7 +13631,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
        addCreatorToken(service);
        addCreatorToken(service, callingPackage);
        if (service != null) {
            // Refuse possible leaked file descriptors
            if (service.hasFileDescriptors()) {
@@ -13890,7 +13893,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        validateServiceInstanceName(instanceName);
        addCreatorToken(service);
        addCreatorToken(service, callingPackage);
        try {
            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                final ComponentName cn = service.getComponent();
@@ -17174,7 +17177,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                Slog.v(TAG_SERVICE,
                        "startServiceInPackage: " + service + " type=" + resolvedType);
            }
            addCreatorToken(service);
            addCreatorToken(service, callingPackage);
            final long origId = Binder.clearCallingIdentity();
            ComponentName res;
            try {
@@ -18002,8 +18005,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        @Override
        public void addCreatorToken(Intent intent) {
            ActivityManagerService.this.addCreatorToken(intent);
        public void addCreatorToken(Intent intent, String creatorPackage) {
            ActivityManagerService.this.addCreatorToken(intent, creatorPackage);
        }
    }
@@ -19160,9 +19163,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        private final Key mKeyFields;
        private final WeakReference<IntentCreatorToken> mRef;
        public IntentCreatorToken(int creatorUid, Intent intent) {
        public IntentCreatorToken(int creatorUid, String creatorPackage, Intent intent) {
            super();
            this.mKeyFields = new Key(creatorUid, intent);
            this.mKeyFields = new Key(creatorUid, creatorPackage, intent);
            mRef = new WeakReference<>(this);
        }
@@ -19170,7 +19173,10 @@ public class ActivityManagerService extends IActivityManager.Stub
            return mKeyFields.mCreatorUid;
        }
        /** {@hide} */
        public String getCreatorPackage() {
            return mKeyFields.mCreatorPackage;
        }
        public static boolean isValid(@NonNull Intent intent) {
            IBinder binder = intent.getCreatorToken();
            IntentCreatorToken token = null;
@@ -19178,7 +19184,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                token = (IntentCreatorToken) binder;
            }
            return token != null && token.mKeyFields.equals(
                    new Key(token.mKeyFields.mCreatorUid, intent));
                    new Key(token.mKeyFields.mCreatorUid, token.mKeyFields.mCreatorPackage,
                            intent));
        }
        @Override
@@ -19202,8 +19209,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        private static class Key {
            private Key(int creatorUid, Intent intent) {
            private Key(int creatorUid, String creatorPackage, Intent intent) {
                this.mCreatorUid = creatorUid;
                this.mCreatorPackage = creatorPackage;
                this.mAction = intent.getAction();
                this.mData = intent.getData();
                this.mType = intent.getType();
@@ -19220,6 +19228,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
            private final int mCreatorUid;
            private final String mCreatorPackage;
            private final String mAction;
            private final Uri mData;
            private final String mType;
@@ -19233,17 +19242,20 @@ public class ActivityManagerService extends IActivityManager.Stub
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                Key key = (Key) o;
                return mCreatorUid == key.mCreatorUid && mFlags == key.mFlags && Objects.equals(
                        mAction, key.mAction) && Objects.equals(mData, key.mData)
                        && Objects.equals(mType, key.mType) && Objects.equals(mPackage,
                        key.mPackage) && Objects.equals(mComponent, key.mComponent)
                return mCreatorUid == key.mCreatorUid && mFlags == key.mFlags
                        && Objects.equals(mCreatorPackage, key.mCreatorPackage)
                        && Objects.equals(mAction, key.mAction)
                        && Objects.equals(mData, key.mData)
                        && Objects.equals(mType, key.mType)
                        && Objects.equals(mPackage, key.mPackage)
                        && Objects.equals(mComponent, key.mComponent)
                        && Objects.equals(mClipDataUris, key.mClipDataUris);
            }
            @Override
            public int hashCode() {
                return Objects.hash(mCreatorUid, mAction, mData, mType, mPackage, mComponent,
                        mFlags, mClipDataUris);
                return Objects.hash(mCreatorUid, mCreatorPackage, mAction, mData, mType, mPackage,
                        mComponent, mFlags, mClipDataUris);
            }
        }
    }
@@ -19254,7 +19266,7 @@ public class ActivityManagerService extends IActivityManager.Stub
     * @param intent The given intent
     * @hide
     */
    public void addCreatorToken(@Nullable Intent intent) {
    public void addCreatorToken(@Nullable Intent intent, String creatorPackage) {
        if (!preventIntentRedirect()) return;
        if (intent == null || intent.getExtraIntentKeys() == null) return;
@@ -19267,7 +19279,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    continue;
                }
                Slog.wtf(TAG, "A creator token is added to an intent.");
                IBinder creatorToken = createIntentCreatorToken(extraIntent);
                IBinder creatorToken = createIntentCreatorToken(extraIntent, creatorPackage);
                if (creatorToken != null) {
                    extraIntent.setCreatorToken(creatorToken);
                }
@@ -19280,15 +19292,15 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    private IBinder createIntentCreatorToken(Intent intent) {
    private IBinder createIntentCreatorToken(Intent intent, String creatorPackage) {
        if (IntentCreatorToken.isValid(intent)) return null;
        int creatorUid = getCallingUid();
        IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, intent);
        IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, creatorPackage, intent);
        IntentCreatorToken token;
        synchronized (sIntentCreatorTokenCache) {
            WeakReference<IntentCreatorToken> ref = sIntentCreatorTokenCache.get(key);
            if (ref == null || ref.get() == null) {
                token = new IntentCreatorToken(creatorUid, intent);
                token = new IntentCreatorToken(creatorUid, creatorPackage, intent);
                sIntentCreatorTokenCache.put(key, token.mRef);
            } else {
                token = ref.get();
Loading