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

Commit d9a831f2 authored by Ioana Alexandru's avatar Ioana Alexandru
Browse files

Revert^3 "Visit URIs in intents associated with notifications."

This reverts commit c82df289.

Reason for revert: this was fixing a hypothetical vulnerability, but we decided that it's safer to not actually check intents at this point; for more information, see b/281044385#comment62

Note: I also removed the TODOs about checking intents, rather than
adding them back.

Change-Id: I19a700bdf12a131a6421341343d4dec55bfe2319
parent e89f7097
Loading
Loading
Loading
Loading
+8 −76
Original line number Diff line number Diff line
@@ -2239,9 +2239,6 @@ public class Notification implements Parcelable
        private void visitUris(@NonNull Consumer<Uri> visitor) {
            visitIconUri(visitor, getIcon());
            if (actionIntent != null) {
                actionIntent.visitUris(visitor);
            }
        }
        @Override
@@ -2957,21 +2954,6 @@ public class Notification implements Parcelable
            }
        }
        // allPendingIntents should contain all associated intents after parcelling, but it may also
        // contain intents added by the app to extras for their own purposes. We only care about
        // checking the intents known and used by system_server, to avoid the confused deputy issue.
        List<PendingIntent> pendingIntents = Arrays.asList(contentIntent, deleteIntent,
                fullScreenIntent);
        for (PendingIntent intent : pendingIntents) {
            if (intent != null) {
                intent.visitUris(visitor);
            }
        }
        if (mBubbleMetadata != null) {
            mBubbleMetadata.visitUris(visitor);
        }
        if (extras != null) {
            visitIconUri(visitor, extras.getParcelable(EXTRA_LARGE_ICON_BIG, Icon.class));
            visitIconUri(visitor, extras.getParcelable(EXTRA_PICTURE_ICON, Icon.class));
@@ -3043,30 +3025,17 @@ public class Notification implements Parcelable
                callPerson.visitUris(visitor);
            }
            visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON, Icon.class));
            // Extras for MediaStyle.
            PendingIntent deviceIntent = extras.getParcelable(EXTRA_MEDIA_REMOTE_INTENT,
                    PendingIntent.class);
            if (deviceIntent != null) {
                deviceIntent.visitUris(visitor);
        }
            if (extras.containsKey(WearableExtender.EXTRA_WEARABLE_EXTENSIONS)) {
                WearableExtender extender = new WearableExtender(this);
                extender.visitUris(visitor);
            }
            if (extras.containsKey(TvExtender.EXTRA_TV_EXTENDER)) {
                TvExtender extender = new TvExtender(this);
                extender.visitUris(visitor);
        if (mBubbleMetadata != null) {
            visitIconUri(visitor, mBubbleMetadata.getIcon());
        }
            if (extras.containsKey(CarExtender.EXTRA_CAR_EXTENDER)) {
                CarExtender extender = new CarExtender(this);
        if (extras != null && extras.containsKey(WearableExtender.EXTRA_WEARABLE_EXTENSIONS)) {
            WearableExtender extender = new WearableExtender(this);
            extender.visitUris(visitor);
        }
    }
    }
    /**
     * @hide
@@ -11459,16 +11428,6 @@ public class Notification implements Parcelable
            }
        }
        private void visitUris(@NonNull Consumer<Uri> visitor) {
            visitIconUri(visitor, getIcon());
            if (mPendingIntent != null) {
                mPendingIntent.visitUris(visitor);
            }
            if (mDeleteIntent != null) {
                mDeleteIntent.visitUris(visitor);
            }
        }
        /**
         * Builder to construct a {@link BubbleMetadata} object.
         */
@@ -12667,9 +12626,6 @@ public class Notification implements Parcelable
        }
        private void visitUris(@NonNull Consumer<Uri> visitor) {
            if (mDisplayIntent != null) {
                mDisplayIntent.visitUris(visitor);
            }
            for (Action action : mActions) {
                action.visitUris(visitor);
            }
@@ -12829,12 +12785,6 @@ public class Notification implements Parcelable
            return mUnreadConversation;
        }
        private void visitUris(@NonNull Consumer<Uri> visitor) {
            if (mUnreadConversation != null) {
                mUnreadConversation.visitUris(visitor);
            }
        }
        /**
         * A class which holds the unread messages from a conversation.
         */
@@ -12986,16 +12936,7 @@ public class Notification implements Parcelable
                        onRead,
                        participants, b.getLong(KEY_TIMESTAMP));
            }
            private void visitUris(@NonNull Consumer<Uri> visitor) {
                if (mReadPendingIntent != null) {
                    mReadPendingIntent.visitUris(visitor);
                }
                if (mReplyPendingIntent != null) {
                    mReplyPendingIntent.visitUris(visitor);
                }
            }
        }
        };
        /**
         * Builder class for {@link CarExtender.UnreadConversation} objects.
@@ -13318,15 +13259,6 @@ public class Notification implements Parcelable
        public boolean isSuppressShowOverApps() {
            return mSuppressShowOverApps;
        }
        private void visitUris(@NonNull Consumer<Uri> visitor) {
            if (mContentIntent != null) {
                mContentIntent.visitUris(visitor);
            }
            if (mDeleteIntent != null) {
                mDeleteIntent.visitUris(visitor);
            }
        }
    }
    /**
+0 −18
Original line number Diff line number Diff line
@@ -44,8 +44,6 @@ import android.content.IntentSender;
import android.content.pm.PackageManager.ResolveInfoFlagsBits;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -71,7 +69,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * A description of an Intent and target action to perform with it.  Instances
@@ -1471,21 +1468,6 @@ public final class PendingIntent implements Parcelable {
        return sb.toString();
    }

    /**
     * See {@link Intent#visitUris(Consumer)}.
     *
     * @hide
     */
    public void visitUris(@NonNull Consumer<Uri> visitor) {
        if (android.app.Flags.visitRiskyUris()) {
            Intent intent = Binder.withCleanCallingIdentity(this::getIntent);

            if (intent != null) {
                intent.visitUris(visitor);
            }
        }
    }

    /** @hide */
    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);
+0 −22
Original line number Diff line number Diff line
@@ -106,7 +106,6 @@ import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.TimeZone;
import java.util.function.Consumer;
/**
 * An intent is an abstract description of an operation to be performed.  It
@@ -8327,27 +8326,6 @@ public class Intent implements Parcelable, Cloneable {
        }
    }
    /**
     * Note all {@link Uri} that are referenced internally, with the expectation that Uri permission
     * grants will need to be issued to ensure the recipient of this object is able to render its
     * contents.
     * See b/281044385 for more context and examples about what happens when this isn't done
     * correctly.
     *
     * @hide
     */
    public void visitUris(@NonNull Consumer<Uri> visitor) {
        if (android.app.Flags.visitRiskyUris()) {
            visitor.accept(mData);
            if (mSelector != null) {
                mSelector.visitUris(visitor);
            }
            if (mOriginalIntent != null) {
                mOriginalIntent.visitUris(visitor);
            }
        }
    }
    public static Intent getIntentOld(String uri) throws URISyntaxException {
        Intent intent = getIntentOld(uri, 0);
        intent.mLocalFlags |= LOCAL_FLAG_FROM_URI;
+0 −43
Original line number Diff line number Diff line
@@ -1044,11 +1044,6 @@ public class RemoteViews implements Parcelable, Filter {
        public int getActionTag() {
            return SET_PENDING_INTENT_TEMPLATE_TAG;
        }

        @Override
        public void visitUris(@NonNull Consumer<Uri> visitor) {
            mPendingIntentTemplate.visitUris(visitor);
        }
    }

    /**
@@ -1524,11 +1519,6 @@ public class RemoteViews implements Parcelable, Filter {
        public int getActionTag() {
            return SET_REMOTE_VIEW_ADAPTER_INTENT_TAG;
        }

        @Override
        public void visitUris(@NonNull Consumer<Uri> visitor) {
            mIntent.visitUris(visitor);
        }
    }

    /**
@@ -1607,11 +1597,6 @@ public class RemoteViews implements Parcelable, Filter {
        public int getActionTag() {
            return SET_ON_CLICK_RESPONSE_TAG;
        }

        @Override
        public void visitUris(@NonNull Consumer<Uri> visitor) {
            mResponse.visitUris(visitor);
        }
    }

    /** Helper action to configure handwriting delegation via {@link PendingIntent}. */
@@ -1659,11 +1644,6 @@ public class RemoteViews implements Parcelable, Filter {
        public int getActionTag() {
            return SET_ON_STYLUS_HANDWRITING_RESPONSE_TAG;
        }

        @Override
        public void visitUris(@NonNull Consumer<Uri> visitor) {
            mPendingIntent.visitUris(visitor);
        }
    }

    /**
@@ -1734,11 +1714,6 @@ public class RemoteViews implements Parcelable, Filter {
        public int getActionTag() {
            return SET_ON_CHECKED_CHANGE_RESPONSE_TAG;
        }

        @Override
        public void visitUris(@NonNull Consumer<Uri> visitor) {
            mResponse.visitUris(visitor);
        }
    }

    /** @hide **/
@@ -2298,10 +2273,6 @@ public class RemoteViews implements Parcelable, Filter {
                    final Icon icon = (Icon) getParameterValue(null);
                    if (icon != null) visitIconUri(icon, visitor);
                    break;
                case INTENT:
                    final Intent intent = (Intent) getParameterValue(null);
                    if (intent != null) intent.visitUris(visitor);
                    break;
                // TODO(b/281044385): Should we do anything about type BUNDLE?
            }
        }
@@ -7221,20 +7192,6 @@ public class RemoteViews implements Parcelable, Filter {
            mElementNames = parcel.createStringArrayList();
        }

        /**
         * See {@link RemoteViews#visitUris(Consumer)}.
         *
         * @hide
         */
        public void visitUris(@NonNull Consumer<Uri> visitor) {
            if (mPendingIntent != null) {
                mPendingIntent.visitUris(visitor);
            }
            if (mFillIntent != null) {
                mFillIntent.visitUris(visitor);
            }
        }

        private void handleViewInteraction(
                View v,
                InteractionHandler handler) {
+3 −27
Original line number Diff line number Diff line
@@ -34,6 +34,9 @@ import android.app.PendingIntent;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.AsyncTask;
@@ -833,33 +836,6 @@ public class RemoteViewsTest {
        verify(visitor, times(1)).accept(eq(icon4S.getUri()));
    }

    @Test
    public void visitUris_intents() {
        RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);

        Uri fillIntentUri = Uri.parse("content://intent/fill");
        views.setOnCheckedChangeResponse(
                R.id.layout,
                RemoteViews.RemoteResponse.fromFillInIntent(new Intent("action", fillIntentUri)));

        Uri pendingIntentUri = Uri.parse("content://intent/pending");
        PendingIntent pendingIntent = getPendingIntentWithUri(pendingIntentUri);
        views.setOnClickResponse(
                R.id.layout,
                RemoteViews.RemoteResponse.fromPendingIntent(pendingIntent));

        Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
        views.visitUris(visitor);
        verify(visitor, times(1)).accept(eq(fillIntentUri));
        verify(visitor, times(1)).accept(eq(pendingIntentUri));
    }

    private PendingIntent getPendingIntentWithUri(Uri uri) {
        return PendingIntent.getActivity(mContext, 0,
                new Intent("action", uri),
                PendingIntent.FLAG_IMMUTABLE);
    }

    @Test
    public void layoutInflaterFactory_nothingSet_returnsNull() {
        final RemoteViews rv = new RemoteViews(mPackage, R.layout.remote_views_test);
Loading