summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityOptions.java4
-rw-r--r--core/java/android/app/ContextImpl.java7
-rw-r--r--core/java/android/app/LoadedApk.java3
-rw-r--r--core/java/android/content/ClipData.java11
-rw-r--r--core/java/android/content/Intent.java20
-rw-r--r--core/java/android/os/BadParcelableException.java8
-rw-r--r--core/java/android/os/BaseBundle.java57
-rw-r--r--core/java/android/os/Bundle.java106
-rw-r--r--core/java/android/os/PersistableBundle.java14
-rw-r--r--core/java/android/view/WindowManagerGlobal.java4
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java8
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java5
-rw-r--r--services/java/com/android/server/SystemServer.java10
14 files changed, 207 insertions, 54 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index f1784559c20e..a6e7d67f1dd3 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -710,6 +710,10 @@ public class ActivityOptions {
/** @hide */
public ActivityOptions(Bundle opts) {
+ // If the remote side sent us bad parcelables, they won't get the
+ // results they want, which is their loss.
+ opts.setDefusable(true);
+
mPackageName = opts.getString(KEY_PACKAGE_NAME);
try {
mUsageTimeReport = opts.getParcelable(KEY_USAGE_TIME_REPORT);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 32ace144ddd8..4fccbc9a79c2 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1332,9 +1332,14 @@ class ContextImpl extends Context {
}
}
try {
- return ActivityManagerNative.getDefault().registerReceiver(
+ final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
+ if (intent != null) {
+ intent.setExtrasClassLoader(getClassLoader());
+ intent.prepareToEnterProcess();
+ }
+ return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index a03fd7236694..c68fd659a25b 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -913,6 +913,8 @@ public final class LoadedApk {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}
+
+ @Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
@@ -996,6 +998,7 @@ public final class LoadedApk {
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
+ intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 0ec58ea40fe4..58630b020491 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -836,6 +836,17 @@ public class ClipData implements Parcelable {
}
}
+ /** {@hide} */
+ public void prepareToEnterProcess() {
+ final int size = mItems.size();
+ for (int i = 0; i < size; i++) {
+ final Item item = mItems.get(i);
+ if (item.mIntent != null) {
+ item.mIntent.prepareToEnterProcess();
+ }
+ }
+ }
+
/** @hide */
public void fixUris(int contentUserHint) {
final int size = mItems.size();
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 35dbc3474865..09aad3b66428 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6037,13 +6037,20 @@ public class Intent implements Parcelable, Cloneable {
return mExtras != null && mExtras.hasFileDescriptors();
}
- /** @hide */
+ /** {@hide} */
public void setAllowFds(boolean allowFds) {
if (mExtras != null) {
mExtras.setAllowFds(allowFds);
}
}
+ /** {@hide} */
+ public void setDefusable(boolean defusable) {
+ if (mExtras != null) {
+ mExtras.setDefusable(defusable);
+ }
+ }
+
/**
* Retrieve extended data from the intent.
*
@@ -8938,6 +8945,17 @@ public class Intent implements Parcelable, Cloneable {
* @hide
*/
public void prepareToEnterProcess() {
+ // We just entered destination process, so we should be able to read all
+ // parcelables inside.
+ setDefusable(true);
+
+ if (mSelector != null) {
+ mSelector.prepareToEnterProcess();
+ }
+ if (mClipData != null) {
+ mClipData.prepareToEnterProcess();
+ }
+
if (mContentUserHint != UserHandle.USER_CURRENT) {
if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) {
fixUris(mContentUserHint);
diff --git a/core/java/android/os/BadParcelableException.java b/core/java/android/os/BadParcelableException.java
index a1c5bb251197..7e0b1a591d0a 100644
--- a/core/java/android/os/BadParcelableException.java
+++ b/core/java/android/os/BadParcelableException.java
@@ -15,11 +15,15 @@
*/
package android.os;
+
import android.util.AndroidRuntimeException;
/**
- * The object you are calling has died, because its hosting process
- * no longer exists.
+ * Exception thrown when a {@link Parcelable} is malformed or otherwise invalid.
+ * <p>
+ * This is typically encountered when a custom {@link Parcelable} object is
+ * passed to another process that doesn't have the same {@link Parcelable} class
+ * in its {@link ClassLoader}.
*/
public class BadParcelableException extends AndroidRuntimeException {
public BadParcelableException(String msg) {
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 5c7137341cd3..6e50155313ca 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -26,7 +26,9 @@ import java.util.ArrayList;
import java.util.Set;
/**
- * A mapping from String values to various types.
+ * A mapping from String keys to values of various types. In most cases, you
+ * should work directly with either the {@link Bundle} or
+ * {@link PersistableBundle} subclass.
*/
public class BaseBundle {
private static final String TAG = "Bundle";
@@ -35,6 +37,32 @@ public class BaseBundle {
// Keep in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
+ /**
+ * Flag indicating that this Bundle is okay to "defuse." That is, it's okay
+ * for system processes to ignore any {@link BadParcelableException}
+ * encountered when unparceling it, leaving an empty bundle in its place.
+ * <p>
+ * This should <em>only</em> be set when the Bundle reaches its final
+ * destination, otherwise a system process may clobber contents that were
+ * destined for an app that could have unparceled them.
+ */
+ static final int FLAG_DEFUSABLE = 1 << 0;
+
+ private static volatile boolean sShouldDefuse = false;
+
+ /**
+ * Set global variable indicating that any Bundles parsed in this process
+ * should be "defused." That is, any {@link BadParcelableException}
+ * encountered will be suppressed and logged, leaving an empty Bundle
+ * instead of crashing.
+ *
+ * @hide
+ */
+ public static void setShouldDefuse(boolean shouldDefuse) {
+ sShouldDefuse = shouldDefuse;
+ }
+
+ /** {@hide} */
static final Parcel EMPTY_PARCEL;
static {
@@ -58,6 +86,9 @@ public class BaseBundle {
*/
private ClassLoader mClassLoader;
+ /** {@hide} */
+ int mFlags;
+
/**
* Constructs a new, empty Bundle that uses a specific ClassLoader for
* instantiating Parcelable and Serializable objects.
@@ -197,6 +228,11 @@ public class BaseBundle {
return;
}
+ if (sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) {
+ Log.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may "
+ + "clobber all data inside!", new Throwable());
+ }
+
if (mParcelledData == EMPTY_PARCEL) {
if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ ": empty");
@@ -221,9 +257,19 @@ public class BaseBundle {
mMap.erase();
mMap.ensureCapacity(N);
}
- mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
- mParcelledData.recycle();
- mParcelledData = null;
+ try {
+ mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
+ } catch (BadParcelableException e) {
+ if (sShouldDefuse) {
+ Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
+ mMap.erase();
+ } else {
+ throw e;
+ }
+ } finally {
+ mParcelledData.recycle();
+ mParcelledData = null;
+ }
if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ " final map: " + mMap);
}
@@ -1371,9 +1417,8 @@ public class BaseBundle {
return;
}
- int magic = parcel.readInt();
+ final int magic = parcel.readInt();
if (magic != BUNDLE_MAGIC) {
- //noinspection ThrowableInstanceNeverThrown
throw new IllegalStateException("Bad magic number for Bundle: 0x"
+ Integer.toHexString(magic));
}
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 74699fd8c0ad..f334e77cfbe6 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -27,11 +27,17 @@ import java.util.ArrayList;
import java.util.List;
/**
- * A mapping from String values to various Parcelable types.
+ * A mapping from String keys to various {@link Parcelable} values.
*
+ * @see PersistableBundle
*/
public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
+ private static final int FLAG_HAS_FDS = 1 << 8;
+ private static final int FLAG_HAS_FDS_KNOWN = 1 << 9;
+ private static final int FLAG_ALLOW_FDS = 1 << 10;
+
public static final Bundle EMPTY;
+
static final Parcel EMPTY_PARCEL;
static {
@@ -40,15 +46,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
EMPTY_PARCEL = BaseBundle.EMPTY_PARCEL;
}
- private boolean mHasFds = false;
- private boolean mFdsKnown = true;
- private boolean mAllowFds = true;
-
/**
* Constructs a new, empty Bundle.
*/
public Bundle() {
super();
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -59,16 +62,18 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
Bundle(Parcel parcelledData) {
super(parcelledData);
-
- mHasFds = mParcelledData.hasFileDescriptors();
- mFdsKnown = true;
+ mFlags = FLAG_HAS_FDS_KNOWN;
+ if (mParcelledData.hasFileDescriptors()) {
+ mFlags |= FLAG_HAS_FDS;
+ }
}
/* package */ Bundle(Parcel parcelledData, int length) {
super(parcelledData, length);
-
- mHasFds = mParcelledData.hasFileDescriptors();
- mFdsKnown = true;
+ mFlags = FLAG_HAS_FDS_KNOWN;
+ if (mParcelledData.hasFileDescriptors()) {
+ mFlags |= FLAG_HAS_FDS;
+ }
}
/**
@@ -80,6 +85,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public Bundle(ClassLoader loader) {
super(loader);
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -90,6 +96,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public Bundle(int capacity) {
super(capacity);
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -100,9 +107,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public Bundle(Bundle b) {
super(b);
-
- mHasFds = b.mHasFds;
- mFdsKnown = b.mFdsKnown;
+ mFlags = b.mFlags;
}
/**
@@ -113,6 +118,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public Bundle(PersistableBundle b) {
super(b);
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -145,14 +151,37 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
return super.getClassLoader();
}
- /** @hide */
+ /** {@hide} */
public boolean setAllowFds(boolean allowFds) {
- boolean orig = mAllowFds;
- mAllowFds = allowFds;
+ final boolean orig = (mFlags & FLAG_ALLOW_FDS) != 0;
+ if (allowFds) {
+ mFlags |= FLAG_ALLOW_FDS;
+ } else {
+ mFlags &= ~FLAG_ALLOW_FDS;
+ }
return orig;
}
/**
+ * Mark if this Bundle is okay to "defuse." That is, it's okay for system
+ * processes to ignore any {@link BadParcelableException} encountered when
+ * unparceling it, leaving an empty bundle in its place.
+ * <p>
+ * This should <em>only</em> be set when the Bundle reaches its final
+ * destination, otherwise a system process may clobber contents that were
+ * destined for an app that could have unparceled them.
+ *
+ * @hide
+ */
+ public void setDefusable(boolean defusable) {
+ if (defusable) {
+ mFlags |= FLAG_DEFUSABLE;
+ } else {
+ mFlags &= ~FLAG_DEFUSABLE;
+ }
+ }
+
+ /**
* Clones the current Bundle. The internal map is cloned, but the keys and
* values to which it refers are copied by reference.
*/
@@ -167,9 +196,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
@Override
public void clear() {
super.clear();
-
- mHasFds = false;
- mFdsKnown = true;
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -182,16 +209,20 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
bundle.unparcel();
mMap.putAll(bundle.mMap);
- // fd state is now known if and only if both bundles already knew
- mHasFds |= bundle.mHasFds;
- mFdsKnown = mFdsKnown && bundle.mFdsKnown;
+ // FD state is now known if and only if both bundles already knew
+ if ((bundle.mFlags & FLAG_HAS_FDS) != 0) {
+ mFlags |= FLAG_HAS_FDS;
+ }
+ if ((bundle.mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
+ }
}
/**
* Reports whether the bundle contains any parcelled file descriptors.
*/
public boolean hasFileDescriptors() {
- if (!mFdsKnown) {
+ if ((mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
boolean fdFound = false; // keep going until we find one or run out of data
if (mParcelledData != null) {
@@ -247,10 +278,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
}
}
- mHasFds = fdFound;
- mFdsKnown = true;
+ if (fdFound) {
+ mFlags |= FLAG_HAS_FDS;
+ }
+ mFlags |= FLAG_HAS_FDS_KNOWN;
}
- return mHasFds;
+ return (mFlags & FLAG_HAS_FDS) != 0;
}
/**
@@ -346,7 +379,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/**
@@ -384,7 +417,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/**
@@ -399,14 +432,14 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
@Nullable ArrayList<? extends Parcelable> value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/** {@hide} */
public void putParcelableList(String key, List<? extends Parcelable> value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/**
@@ -421,7 +454,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
@Nullable SparseArray<? extends Parcelable> value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/**
@@ -1074,7 +1107,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
@Override
public void writeToParcel(Parcel parcel, int flags) {
- final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
+ final boolean oldAllowFds = parcel.pushAllowFds((mFlags & FLAG_ALLOW_FDS) != 0);
try {
super.writeToParcelInner(parcel, flags);
} finally {
@@ -1089,8 +1122,10 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public void readFromParcel(Parcel parcel) {
super.readFromParcelInner(parcel);
- mHasFds = mParcelledData.hasFileDescriptors();
- mFdsKnown = true;
+ mFlags = FLAG_HAS_FDS_KNOWN;
+ if (mParcelledData.hasFileDescriptors()) {
+ mFlags |= FLAG_HAS_FDS;
+ }
}
@Override
@@ -1105,5 +1140,4 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
}
return "Bundle[" + mMap.toString() + "]";
}
-
}
diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java
index 5872f7438904..b947c97dffc7 100644
--- a/core/java/android/os/PersistableBundle.java
+++ b/core/java/android/os/PersistableBundle.java
@@ -18,7 +18,9 @@ package android.os;
import android.annotation.Nullable;
import android.util.ArrayMap;
+
import com.android.internal.util.XmlUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -26,9 +28,11 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
/**
- * A mapping from String values to various types that can be saved to persistent and later
- * restored.
+ * A mapping from String keys to values of various types. The set of types
+ * supported by this class is purposefully restricted to simple objects that can
+ * safely be persisted to and restored from disk.
*
+ * @see Bundle
*/
public final class PersistableBundle extends BaseBundle implements Cloneable, Parcelable,
XmlUtils.WriteMapCallback {
@@ -57,6 +61,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
*/
public PersistableBundle() {
super();
+ mFlags = FLAG_DEFUSABLE;
}
/**
@@ -67,6 +72,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
*/
public PersistableBundle(int capacity) {
super(capacity);
+ mFlags = FLAG_DEFUSABLE;
}
/**
@@ -77,6 +83,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
*/
public PersistableBundle(PersistableBundle b) {
super(b);
+ mFlags = b.mFlags;
}
@@ -101,6 +108,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
*/
private PersistableBundle(ArrayMap<String, Object> map) {
super();
+ mFlags = FLAG_DEFUSABLE;
// First stuff everything in.
putAll(map);
@@ -123,6 +131,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
/* package */ PersistableBundle(Parcel parcelledData, int length) {
super(parcelledData, length);
+ mFlags = FLAG_DEFUSABLE;
}
/**
@@ -278,5 +287,4 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
}
return "PersistableBundle[" + mMap.toString() + "]";
}
-
}
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index a1cbc1d07575..887cc3acb64a 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -170,7 +170,7 @@ public final class WindowManagerGlobal {
sWindowManagerService = getWindowManagerService();
ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());
} catch (RemoteException e) {
- Log.e(TAG, "Failed to get WindowManagerService, cannot set animator scale", e);
+ throw e.rethrowFromSystemServer();
}
}
return sWindowManagerService;
@@ -192,7 +192,7 @@ public final class WindowManagerGlobal {
},
imm.getClient(), imm.getInputContext());
} catch (RemoteException e) {
- Log.e(TAG, "Failed to open window session", e);
+ throw e.rethrowFromSystemServer();
}
}
return sWindowSession;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 987b5ea2db09..743912a12935 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -207,6 +207,10 @@ public class SettingsProvider extends ContentProvider {
@Override
public Bundle call(String method, String name, Bundle args) {
+ // If the remote side sent us bad parcelables, they won't get the
+ // results they want, which is their loss.
+ if (args != null) args.setDefusable(true);
+
final int requestingUserId = getRequestingUserId(args);
switch (method) {
case Settings.CALL_METHOD_GET_GLOBAL: {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 95dbd0f94f96..6361db59b0f5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6913,6 +6913,14 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ // We're going to be splicing together extras before sending, so we're
+ // okay poking into any contained extras.
+ if (intents != null) {
+ for (int i = 0; i < intents.length; i++) {
+ intents[i].setDefusable(true);
+ }
+ }
+
final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 3baf894a67f0..703d81223e0e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2298,6 +2298,11 @@ public class NotificationManagerService extends SystemService {
// Sanitize inputs
notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN,
Notification.PRIORITY_MAX);
+ if (notification.extras != null) {
+ // If the remote side sent us bad parcelables, they won't get the
+ // results they want, which is their loss.
+ notification.extras.setDefusable(true);
+ }
// setup local book-keeping
final StatusBarNotification n = new StatusBarNotification(
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 19c073ccf4dc..5975405f5216 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -28,6 +28,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
+import android.os.BaseBundle;
import android.os.Build;
import android.os.Environment;
import android.os.FactoryTest;
@@ -35,7 +36,6 @@ import android.os.FileUtils;
import android.os.IPowerManager;
import android.os.Looper;
import android.os.PowerManager;
-import android.os.RecoverySystem;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StrictMode;
@@ -53,6 +53,7 @@ import com.android.internal.R;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
import com.android.internal.os.ZygoteInit;
+import com.android.internal.widget.ILockSettings;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accounts.AccountManagerService;
import com.android.server.am.ActivityManagerService;
@@ -69,10 +70,9 @@ import com.android.server.hdmi.HdmiControlService;
import com.android.server.input.InputManagerService;
import com.android.server.job.JobSchedulerService;
import com.android.server.lights.LightsService;
-import com.android.internal.widget.ILockSettings;
+import com.android.server.media.MediaResourceMonitorService;
import com.android.server.media.MediaRouterService;
import com.android.server.media.MediaSessionService;
-import com.android.server.media.MediaResourceMonitorService;
import com.android.server.media.projection.MediaProjectionManagerService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
@@ -271,6 +271,10 @@ public final class SystemServer {
// explicitly specifying a user.
Environment.setUserRequired(true);
+ // Within the system server, any incoming Bundles should be defused
+ // to avoid throwing BadParcelableException.
+ BaseBundle.setShouldDefuse(true);
+
// Ensure binder calls into the system always run at foreground priority.
BinderInternal.disableBackgroundScheduling(true);