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

Commit f929d5a5 authored by Azhara Assanova's avatar Azhara Assanova
Browse files

Make mutable PendingIntent explicit

Starting from target SDK U, we will block creation of mutable
PendingIntents with implicit Intents because attackers can mutate the
Intent object within and launch altered behavior on behalf of victim
apps. For more details on the vulnerability, see go/pendingintent-rca.

From a quick analysis, we concluded that the PendingIntent here was only
destined to the test app/to the app, so it was made explicit. Reviewers,
please call out if this is not the case.

Bug: 236704164
Bug: 229362273
Test: atest IntentSenderTest
Test: atest RemoteViewsTest
Test: atest NotificationTest
Test: atest SuggestionTest
Test: atest NotificationStressTests
Test: atest android.content.pm.PackageSessionTests
Change-Id: I6721b52b63c406724855f5e3824281ef6965fa75
parent 397065c0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -92,9 +92,9 @@ class PackageSessionTests {
        }

        fun makeIntentSender(sessionId: Int) = PendingIntent.getBroadcast(context, sessionId,
                Intent(INTENT_ACTION),
                Intent(INTENT_ACTION).setPackage(context.packageName),
                PendingIntent.FLAG_UPDATE_CURRENT
                        or PendingIntent.FLAG_MUTABLE_UNAUDITED).intentSender
                        or PendingIntent.FLAG_MUTABLE).intentSender

        fun getResult(unit: TimeUnit, timeout: Long) = results.poll(timeout, unit)

+5 −2
Original line number Diff line number Diff line
@@ -248,7 +248,9 @@ public class NotificationTest {

    @Test
    public void allPendingIntents_containsCustomRemoteViews() {
        PendingIntent intent = PendingIntent.getActivity(mContext, 0, new Intent("test"), PendingIntent.FLAG_MUTABLE_UNAUDITED);
        PendingIntent intent = PendingIntent.getActivity(mContext, 0,
                new Intent("test").setPackage(mContext.getPackageName()),
                PendingIntent.FLAG_MUTABLE);

        RemoteViews contentView = new RemoteViews(mContext.getPackageName(), 0 /* layoutId */);
        contentView.setOnClickPendingIntent(1 /* id */, intent);
@@ -1578,7 +1580,8 @@ public class NotificationTest {
     * Creates a PendingIntent with the given action.
     */
    private PendingIntent createPendingIntent(String action) {
        return PendingIntent.getActivity(mContext, 0, new Intent(action),
        return PendingIntent.getActivity(mContext, 0,
                new Intent(action).setPackage(mContext.getPackageName()),
                PendingIntent.FLAG_MUTABLE);
    }
}
+12 −6
Original line number Diff line number Diff line
@@ -32,14 +32,16 @@ public class IntentSenderTest extends BroadcastTest {
        registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_GRANTED);
        addIntermediate("after-register");
        PendingIntent is = PendingIntent.getBroadcast(getContext(), 0,
                makeBroadcastIntent(BROADCAST_REGISTERED), PendingIntent.FLAG_MUTABLE_UNAUDITED);
                makeBroadcastIntent(BROADCAST_REGISTERED).setPackage(getContext().getPackageName()),
                PendingIntent.FLAG_MUTABLE);
        is.send();
        waitForResultOrThrow(BROADCAST_TIMEOUT);
        is.cancel();
    }

    public void testRegisteredReceivePermissionDenied() throws Exception {
        final Intent intent = makeBroadcastIntent(BROADCAST_REGISTERED);
        final Intent intent = makeBroadcastIntent(BROADCAST_REGISTERED)
                .setPackage(getContext().getPackageName());

        setExpectedReceivers(new String[]{RECEIVER_RESULTS});
        registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_DENIED);
@@ -52,7 +54,8 @@ public class IntentSenderTest extends BroadcastTest {
            }
        };

        PendingIntent is = PendingIntent.getBroadcast(getContext(), 0, intent, PendingIntent.FLAG_MUTABLE_UNAUDITED);
        PendingIntent is = PendingIntent.getBroadcast(getContext(), 0, intent,
                PendingIntent.FLAG_MUTABLE);
        is.send(Activity.RESULT_CANCELED, finish, null);
        waitForResultOrThrow(BROADCAST_TIMEOUT);
        is.cancel();
@@ -61,14 +64,16 @@ public class IntentSenderTest extends BroadcastTest {
    public void testLocalReceivePermissionGranted() throws Exception {
        setExpectedReceivers(new String[]{RECEIVER_LOCAL});
        PendingIntent is = PendingIntent.getBroadcast(getContext(), 0,
                makeBroadcastIntent(BROADCAST_LOCAL_GRANTED), PendingIntent.FLAG_MUTABLE_UNAUDITED);
                makeBroadcastIntent(BROADCAST_LOCAL_GRANTED)
                        .setPackage(getContext().getPackageName()), PendingIntent.FLAG_MUTABLE);
        is.send();
        waitForResultOrThrow(BROADCAST_TIMEOUT);
        is.cancel();
    }

    public void testLocalReceivePermissionDenied() throws Exception {
        final Intent intent = makeBroadcastIntent(BROADCAST_LOCAL_DENIED);
        final Intent intent = makeBroadcastIntent(BROADCAST_LOCAL_DENIED)
                .setPackage(getContext().getPackageName());

        setExpectedReceivers(new String[]{RECEIVER_RESULTS});

@@ -79,7 +84,8 @@ public class IntentSenderTest extends BroadcastTest {
            }
        };

        PendingIntent is = PendingIntent.getBroadcast(getContext(), 0, intent, PendingIntent.FLAG_MUTABLE_UNAUDITED);
        PendingIntent is = PendingIntent.getBroadcast(getContext(), 0, intent,
                PendingIntent.FLAG_MUTABLE);
        is.send(Activity.RESULT_CANCELED, finish, null);
        waitForResultOrThrow(BROADCAST_TIMEOUT);
        is.cancel();
+2 −1
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@ public class SuggestionTest {
    public void setUp() {
        final Context context = InstrumentationRegistry.getContext();
        mTestIntent = PendingIntent.getActivity(context, 0 /* requestCode */,
                new Intent(), PendingIntent.FLAG_MUTABLE_UNAUDITED /* flags */);
                new Intent().setPackage(context.getPackageName()),
                PendingIntent.FLAG_MUTABLE /* flags */);
        mIcon = Icon.createWithBitmap(Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888));
    }

+17 −7
Original line number Diff line number Diff line
@@ -324,7 +324,9 @@ public class RemoteViewsTest {
        RemoteViews nested = new RemoteViews(mPackage, R.layout.remote_views_text);
        nested.setOnClickPendingIntent(
                R.id.text,
                PendingIntent.getActivity(mContext, 0, new Intent(), PendingIntent.FLAG_MUTABLE)
                PendingIntent.getActivity(mContext, 0,
                        new Intent().setPackage(mContext.getPackageName()),
                        PendingIntent.FLAG_MUTABLE)
        );

        RemoteViews listItem = new RemoteViews(mPackage, R.layout.remote_view_host);
@@ -341,7 +343,9 @@ public class RemoteViewsTest {
        RemoteViews inner = new RemoteViews(mPackage, R.layout.remote_views_text);
        inner.setOnClickPendingIntent(
                R.id.text,
                PendingIntent.getActivity(mContext, 0, new Intent(), PendingIntent.FLAG_MUTABLE)
                PendingIntent.getActivity(mContext, 0,
                        new Intent().setPackage(mContext.getPackageName()),
                        PendingIntent.FLAG_MUTABLE)
        );

        RemoteViews listItem = new RemoteViews(inner, inner);
@@ -357,7 +361,9 @@ public class RemoteViewsTest {
        RemoteViews inner = new RemoteViews(mPackage, R.layout.remote_views_text);
        inner.setOnClickPendingIntent(
                R.id.text,
                PendingIntent.getActivity(mContext, 0, new Intent(), PendingIntent.FLAG_MUTABLE)
                PendingIntent.getActivity(mContext, 0,
                        new Intent().setPackage(mContext.getPackageName()),
                        PendingIntent.FLAG_MUTABLE)
        );

        RemoteViews listItem = new RemoteViews(
@@ -559,7 +565,9 @@ public class RemoteViewsTest {
        RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
        for (int i = 1; i < 10; i++) {
            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0,
                    new Intent("android.widget.RemoteViewsTest_" + i), PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
                    new Intent("android.widget.RemoteViewsTest_" + i)
                            .setPackage(mContext.getPackageName()),
                    PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE);
            views.setOnClickPendingIntent(i, pi);
        }
        try {
@@ -575,7 +583,8 @@ public class RemoteViewsTest {

        RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0,
                new Intent("test"), PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
                new Intent("test").setPackage(mContext.getPackageName()),
                PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE);
        views.setOnClickPendingIntent(1, pi);
        RemoteViews withCookie = parcelAndRecreateWithPendingIntentCookie(views, whitelistToken);

@@ -606,8 +615,9 @@ public class RemoteViewsTest {
    public void sharedElement_pendingIntent_notifyParent() throws Exception {
        RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0,
                new Intent("android.widget.RemoteViewsTest_shared_element"),
                PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
                new Intent("android.widget.RemoteViewsTest_shared_element")
                        .setPackage(mContext.getPackageName()),
                PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE);
        views.setOnClickResponse(R.id.image, RemoteViews.RemoteResponse.fromPendingIntent(pi)
                .addSharedElement(0, "e0")
                .addSharedElement(1, "e1")
Loading