From d136e51a99df5275eaafdde407e89e78c02b829b Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 9 Mar 2016 22:30:56 -0700 Subject: [PATCH] Defuse Bundles parsed by the system process. It's easy for apps to throw custom Parcelables into Bundles, but if the system tries peeking inside one of these Bundles, it triggers a BadParcelableException. If that Bundle was passed away from the Binder thread that delivered it into the system, we end up with a nasty runtime restart. This change mitigates this trouble by "defusing" any Bundles parsed by the system server. That is, if it encounters BadParcelableException while unpacking a Bundle, it logs and delivers an empty Bundle as the result. Simultaneously, to help catch the system process sticking its fingers into Bundles that are destined for other processes, a Bundle now tracks if it's "defusable." For example, any Intents delivered through ActivityThread are marked as being defusable, since they've arrived at their final destination. Any other Bundles are considered to be "in transit" and we log if the system tries unparceling them. Merges several Parcel boolean fields into a flags int. Add better docs to several classes. Bug: 27581063 Change-Id: I28cf3e7439503b5dc9a429bafae5eb48f21f0d93 --- core/java/android/app/ActivityOptions.java | 4 + core/java/android/app/ContextImpl.java | 7 +- core/java/android/app/LoadedApk.java | 3 + core/java/android/content/ClipData.java | 11 ++ core/java/android/content/Intent.java | 20 +++- .../android/os/BadParcelableException.java | 8 +- core/java/android/os/BaseBundle.java | 57 +++++++++- core/java/android/os/Bundle.java | 106 ++++++++++++------ core/java/android/os/PersistableBundle.java | 14 ++- .../android/view/WindowManagerGlobal.java | 4 +- .../providers/settings/SettingsProvider.java | 4 + .../server/am/ActivityManagerService.java | 8 ++ .../NotificationManagerService.java | 5 + .../java/com/android/server/SystemServer.java | 10 +- 14 files changed, 207 insertions(+), 54 deletions(-) diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index f1784559c20e7..a6e7d67f1dd3e 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 32ace144ddd82..4fccbc9a79c25 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 a03fd72366946..c68fd659a25bf 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(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 0ec58ea40fe42..58630b0204913 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 35dbc3474865b..09aad3b664280 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 a1c5bb2511971..7e0b1a591d0a3 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. + *

+ * 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 5c7137341cd39..6e50155313ca0 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. + *

+ * This should only 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 74699fd8c0ade..f334e77cfbe69 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,13 +151,36 @@ 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. + *

+ * This should only 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 value) { unparcel(); mMap.put(key, value); - mFdsKnown = false; + mFlags &= ~FLAG_HAS_FDS_KNOWN; } /** {@hide} */ public void putParcelableList(String key, List 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 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 5872f7438904e..b947c97dffc77 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 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 a1cbc1d075756..887cc3acb64a4 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 987b5ea2db092..743912a129353 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 95dbd0f94f965..6361db59b0f5a 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 3baf894a67f0b..703d81223e0e2 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 19c073ccf4dca..5975405f5216e 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);