summaryrefslogtreecommitdiff
path: root/core/java/android/content/Intent.java
diff options
context:
space:
mode:
authorMichael Groover <mpgroover@google.com>2021-02-26 18:27:16 -0800
committerMichael Groover <mpgroover@google.com>2021-02-26 18:27:16 -0800
commit96a995dce0fc22b03aa882c76df0d5b03f026c09 (patch)
tree9e71510e2ee10c74defc9fac733798489cca8924 /core/java/android/content/Intent.java
parent85bde7b023342127bdd85a8eadcb7df0d83221c4 (diff)
Report UnsafeIntentLaunchViolation for unfiltered extras copy
Android 12 introduced a new StrictMode check to report an unsafe Intent launch; initially this was intended to warn developers when a launched Intent could potentially have originated from an external source. This commit updates this check to also report when an Intent is being launched with potentially unfiltered data; that is data that was copied without sanitation / validation from a parceled Intent or Bundle. When a violation is reported for unfiltered data the developer should replace the #putExtras call with individual calls to #putExtra to only include the items expected in the extras. Bug: 181374760 Test: atest StrictModeTest Change-Id: Id2b6baf439716367f4709d03832ceb601f9f009e
Diffstat (limited to 'core/java/android/content/Intent.java')
-rw-r--r--core/java/android/content/Intent.java30
1 files changed, 26 insertions, 4 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d53d20a8b192..d352b273f882 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6755,6 +6755,12 @@ public class Intent implements Parcelable, Cloneable {
*/
private static final int LOCAL_FLAG_FROM_PROTECTED_COMPONENT = 1 << 2;
+ /**
+ * Local flag indicating this instance had unfiltered extras copied into it. This could be
+ * from either {@link #putExtras(Intent)} when an unparceled Intent is provided or {@link
+ * #putExtras(Bundle)} when the provided Bundle has not been unparceled.
+ */
+ private static final int LOCAL_FLAG_UNFILTERED_EXTRAS = 1 << 3;
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// toUri() and parseUri() options.
@@ -10009,6 +10015,15 @@ public class Intent implements Parcelable, Cloneable {
mExtras.putAll(src.mExtras);
}
}
+ // If the provided Intent was unparceled and this is not an Intent delivered to a protected
+ // component then mark the extras as unfiltered. An Intent delivered to a protected
+ // component had to come from a trusted component, and if unfiltered data was copied to the
+ // delivered Intent then it would have been reported when that Intent left the sending
+ // process.
+ if ((src.mLocalFlags & LOCAL_FLAG_FROM_PARCEL) != 0
+ && (src.mLocalFlags & LOCAL_FLAG_FROM_PROTECTED_COMPONENT) == 0) {
+ mLocalFlags |= LOCAL_FLAG_UNFILTERED_EXTRAS;
+ }
return this;
}
@@ -10023,6 +10038,10 @@ public class Intent implements Parcelable, Cloneable {
* @see #removeExtra
*/
public @NonNull Intent putExtras(@NonNull Bundle extras) {
+ // If the provided Bundle has not yet been unparceled then treat this as unfiltered extras.
+ if (extras.isParcelled()) {
+ mLocalFlags |= LOCAL_FLAG_UNFILTERED_EXTRAS;
+ }
if (mExtras == null) {
mExtras = new Bundle();
}
@@ -11328,10 +11347,13 @@ public class Intent implements Parcelable, Cloneable {
}
// Detect cases where we're about to launch a potentially unsafe intent
- if ((mLocalFlags & LOCAL_FLAG_FROM_PARCEL) != 0
- && (mLocalFlags & LOCAL_FLAG_FROM_PROTECTED_COMPONENT) == 0
- && StrictMode.vmUnsafeIntentLaunchEnabled()) {
- StrictMode.onUnsafeIntentLaunch(this);
+ if (StrictMode.vmUnsafeIntentLaunchEnabled()) {
+ if ((mLocalFlags & LOCAL_FLAG_FROM_PARCEL) != 0
+ && (mLocalFlags & LOCAL_FLAG_FROM_PROTECTED_COMPONENT) == 0) {
+ StrictMode.onUnsafeIntentLaunch(this);
+ } else if ((mLocalFlags & LOCAL_FLAG_UNFILTERED_EXTRAS) != 0) {
+ StrictMode.onUnsafeIntentLaunch(this);
+ }
}
}