diff options
| author | 2024-01-18 07:27:57 +0000 | |
|---|---|---|
| committer | 2024-01-19 02:25:10 +0000 | |
| commit | 07c634ab7c1fab39bfc9c4fbae118564d99fea8a (patch) | |
| tree | 632e9899b9d919bd018815b37f2b2f3d8b3b538a | |
| parent | d2a260e5650ed400a1cfcb4fd2876a57aa6e5908 (diff) | |
Check Bundle when creating/sending a PendingIntent
When creating a PendingIntent the bundle must never contain any sender
options and when sending no creator options.
The change is target SDK gated to make sure old apps don't get broken.
Test: atest ActivityStarterTests BackgroundActivityLaunchTest
Bug: 320664730
Change-Id: I203b9e5864c14c85a8781139e4d906c74fc8c655
3 files changed, 23 insertions, 3 deletions
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 0261f0a02174..1ac08ac4cd24 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -179,6 +179,14 @@ public final class PendingIntent implements Parcelable { @Overridable public static final long BLOCK_MUTABLE_IMPLICIT_PENDING_INTENT = 236704164L; + /** + * Validate options passed in as bundle. + * @hide + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + public static final long PENDING_INTENT_OPTIONS_CHECK = 320664730L; + /** @hide */ @IntDef(flag = true, value = { diff --git a/services/core/java/com/android/server/am/PendingIntentController.java b/services/core/java/com/android/server/am/PendingIntentController.java index a20623cd1ee9..5df910716ba6 100644 --- a/services/core/java/com/android/server/am/PendingIntentController.java +++ b/services/core/java/com/android/server/am/PendingIntentController.java @@ -30,6 +30,7 @@ import android.app.ActivityOptions; import android.app.AppGlobals; import android.app.PendingIntent; import android.app.PendingIntentStats; +import android.app.compat.CompatChanges; import android.content.IIntentSender; import android.content.Intent; import android.os.Binder; @@ -136,6 +137,11 @@ public class PendingIntentController { + "intent creator (" + packageName + ") because this option is meant for the pending intent sender"); + if (CompatChanges.isChangeEnabled(PendingIntent.PENDING_INTENT_OPTIONS_CHECK, + callingUid)) { + throw new IllegalArgumentException("pendingIntentBackgroundActivityStartMode " + + "must not be set when creating a PendingIntent"); + } opts.setPendingIntentBackgroundActivityStartMode( ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED); } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 10d5fd3f77b6..95e130ed1194 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -406,6 +406,9 @@ public final class PendingIntentRecord extends IIntentSender.Stub { String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + if (intent != null) intent.setDefusable(true); if (options != null) options.setDefusable(true); @@ -458,6 +461,12 @@ public final class PendingIntentRecord extends IIntentSender.Stub { + key.packageName + ") because this option is meant for the pending intent " + "creator"); + if (CompatChanges.isChangeEnabled(PendingIntent.PENDING_INTENT_OPTIONS_CHECK, + callingUid)) { + throw new IllegalArgumentException( + "pendingIntentCreatorBackgroundActivityStartMode " + + "must not be set when sending a PendingIntent"); + } opts.setPendingIntentCreatorBackgroundActivityStartMode( ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED); } @@ -494,9 +503,6 @@ public final class PendingIntentRecord extends IIntentSender.Stub { } // We don't hold the controller lock beyond this point as we will be calling into AM and WM. - final int callingUid = Binder.getCallingUid(); - final int callingPid = Binder.getCallingPid(); - // Only system senders can declare a broadcast to be alarm-originated. We check // this here rather than in the general case handling below to fail before the other // invocation side effects such as allowlisting. |