diff options
10 files changed, 61 insertions, 18 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index e9d0846fe71c..cb1bee5c0376 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -957,7 +957,7 @@ public class Notification implements Parcelable if (in.readInt() == 1) { actionIntent = PendingIntent.CREATOR.createFromParcel(in); } - mExtras = in.readBundle(); + mExtras = Bundle.setDefusable(in.readBundle(), true); mRemoteInputs = in.createTypedArray(RemoteInput.CREATOR); } @@ -1487,7 +1487,7 @@ public class Notification implements Parcelable mSortKey = parcel.readString(); - extras = parcel.readBundle(); // may be null + extras = Bundle.setDefusable(parcel.readBundle(), true); // may be null actions = parcel.createTypedArray(Action.CREATOR); // may be null diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 1c3f45cdbde8..bc2d788bf4c8 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -394,6 +394,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Bundle call( String callingPkg, String method, @Nullable String arg, @Nullable Bundle extras) { + Bundle.setDefusable(extras, true); final String original = setCallingPackage(callingPkg); try { return ContentProvider.this.call(method, arg, extras); @@ -412,6 +413,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType, Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException { + Bundle.setDefusable(opts, true); validateIncomingUri(uri); uri = getUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, "r", null); diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 441f188f91e6..cd67b3ee8a3e 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -1412,7 +1412,9 @@ public abstract class ContentResolver { throw new IllegalArgumentException("Unknown URI " + uri); } try { - return provider.call(mPackageName, method, arg, extras); + final Bundle res = provider.call(mPackageName, method, arg, extras); + Bundle.setDefusable(res, true); + return res; } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity // Manager will kill this process shortly anyway. diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java index f793d76520de..541ebbd32f11 100644 --- a/core/java/android/content/SyncRequest.java +++ b/core/java/android/content/SyncRequest.java @@ -147,7 +147,7 @@ public class SyncRequest implements Parcelable { } private SyncRequest(Parcel in) { - mExtras = in.readBundle(); + mExtras = Bundle.setDefusable(in.readBundle(), true); mSyncFlexTimeSecs = in.readLong(); mSyncRunTimeSecs = in.readLong(); mIsPeriodic = (in.readInt() != 0); diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index 1097cadd55dc..05dd48b12e55 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -181,6 +181,14 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } } + /** {@hide} */ + public static Bundle setDefusable(Bundle bundle, boolean defusable) { + if (bundle != null) { + bundle.setDefusable(defusable); + } + return bundle; + } + /** * Clones the current Bundle. The internal map is cloned, but the keys and * values to which it refers are copied by reference. diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 4d0d1bd64b0e..50f0badf6ac1 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -891,7 +891,7 @@ public class Location implements Parcelable { l.mSpeed = in.readFloat(); l.mBearing = in.readFloat(); l.mAccuracy = in.readFloat(); - l.mExtras = in.readBundle(); + l.mExtras = Bundle.setDefusable(in.readBundle(), true); return l; } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 743912a12935..987b5ea2db09 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -207,10 +207,6 @@ 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/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 322df04ee2ac..1632f92dd40c 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -797,6 +797,7 @@ public class AccountManagerService @Override public boolean addAccountExplicitly(Account account, String password, Bundle extras) { + Bundle.setDefusable(extras, true); final int callingUid = Binder.getCallingUid(); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "addAccountExplicitly: " + account @@ -873,6 +874,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); if (result != null && result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { // Create a Session for the target user and pass in the bundle @@ -946,6 +948,7 @@ public class AccountManagerService private void completeCloningAccount(IAccountManagerResponse response, final Bundle accountCredentials, final Account account, final UserAccounts targetUser, final int parentUserId){ + Bundle.setDefusable(accountCredentials, true); long id = clearCallingIdentity(); try { new Session(targetUser, response, account.type, false, @@ -975,6 +978,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); // TODO: Anything to do if if succedded? // TODO: If it failed: Show error notification? Should we remove the shadow // account to avoid retries? @@ -996,6 +1000,7 @@ public class AccountManagerService private boolean addAccountInternal(UserAccounts accounts, Account account, String password, Bundle extras, boolean restricted, int callingUid) { + Bundle.setDefusable(extras, true); if (account == null) { return false; } @@ -1128,6 +1133,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); IAccountManagerResponse response = getResponseAndClose(); if (response != null) { try { @@ -1429,6 +1435,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) && !result.containsKey(AccountManager.KEY_INTENT)) { final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT); @@ -1880,6 +1887,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); if (result != null) { String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL); Bundle bundle = new Bundle(); @@ -1904,6 +1912,7 @@ public class AccountManagerService final boolean notifyOnAuthFailure, final boolean expectActivityLaunch, final Bundle loginOptions) { + Bundle.setDefusable(loginOptions, true); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "getAuthToken: " + account + ", response " + response @@ -2044,6 +2053,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); if (result != null) { if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) { Intent intent = newGrantCredentialsPermissionIntent( @@ -2206,6 +2216,7 @@ public class AccountManagerService public void addAccount(final IAccountManagerResponse response, final String accountType, final String authTokenType, final String[] requiredFeatures, final boolean expectActivityLaunch, final Bundle optionsIn) { + Bundle.setDefusable(optionsIn, true); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "addAccount: accountType " + accountType + ", response " + response @@ -2280,6 +2291,7 @@ public class AccountManagerService public void addAccountAsUser(final IAccountManagerResponse response, final String accountType, final String authTokenType, final String[] requiredFeatures, final boolean expectActivityLaunch, final Bundle optionsIn, int userId) { + Bundle.setDefusable(optionsIn, true); int callingUid = Binder.getCallingUid(); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "addAccount: accountType " + accountType @@ -2366,6 +2378,7 @@ public class AccountManagerService final String[] requiredFeatures, final boolean expectActivityLaunch, final Bundle optionsIn) { + Bundle.setDefusable(optionsIn, true); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "startAddAccountSession: accountType " + accountType @@ -2459,6 +2472,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); mNumResults++; Intent intent = null; if (result != null @@ -2543,6 +2557,7 @@ public class AccountManagerService boolean expectActivityLaunch, Bundle appInfo, int userId) { + Bundle.setDefusable(sessionBundle, true); int callingUid = Binder.getCallingUid(); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, @@ -2698,6 +2713,7 @@ public class AccountManagerService final Bundle options, final boolean expectActivityLaunch, int userId) { + Bundle.setDefusable(options, true); int callingUid = Binder.getCallingUid(); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "confirmCredentials: " + account @@ -2741,6 +2757,7 @@ public class AccountManagerService public void updateCredentials(IAccountManagerResponse response, final Account account, final String authTokenType, final boolean expectActivityLaunch, final Bundle loginOptions) { + Bundle.setDefusable(loginOptions, true); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "updateCredentials: " + account + ", response " + response @@ -2784,6 +2801,7 @@ public class AccountManagerService final String authTokenType, final boolean expectActivityLaunch, final Bundle loginOptions) { + Bundle.setDefusable(loginOptions, true); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "startUpdateCredentialsSession: " + account + ", response " + response @@ -2891,6 +2909,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); IAccountManagerResponse response = getResponseAndClose(); if (response == null) { return; @@ -3051,6 +3070,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); mNumResults++; if (result == null) { onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle"); @@ -3685,6 +3705,7 @@ public class AccountManagerService @Override public void onResult(Bundle result) { + Bundle.setDefusable(result, true); mNumResults++; Intent intent = null; if (result != null) { diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 03191a0977cc..28170f2a6b1c 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -286,6 +286,7 @@ public final class ContentService extends IContentService.Stub { UserHandle.getCallingUserId()); } + @Override public void unregisterContentObserver(IContentObserver observer) { if (observer == null) { throw new IllegalArgumentException("You must pass a valid observer"); @@ -409,7 +410,9 @@ public final class ContentService extends IContentService.Stub { } } + @Override public void requestSync(Account account, String authority, Bundle extras) { + Bundle.setDefusable(extras, true); ContentResolver.validateSyncExtrasBundle(extras); int userId = UserHandle.getCallingUserId(); int uId = Binder.getCallingUid(); @@ -438,6 +441,7 @@ public final class ContentService extends IContentService.Stub { * Depending on the request, we enqueue to suit in the SyncManager. * @param request The request object. Validation of this object is done by its builder. */ + @Override public void sync(SyncRequest request) { syncAsUser(request, UserHandle.getCallingUserId()); } @@ -446,6 +450,7 @@ public final class ContentService extends IContentService.Stub { * If the user id supplied is different to the calling user, the caller must hold the * INTERACT_ACROSS_USERS_FULL permission. */ + @Override public void syncAsUser(SyncRequest request, int userId) { enforceCrossUserPermission(userId, "no permission to request sync as user: " + userId); int callerUid = Binder.getCallingUid(); @@ -544,6 +549,7 @@ public final class ContentService extends IContentService.Stub { } } + @Override public void cancelRequest(SyncRequest request) { SyncManager syncManager = getSyncManager(); if (syncManager == null) return; @@ -678,6 +684,7 @@ public final class ContentService extends IContentService.Stub { @Override public void addPeriodicSync(Account account, String authority, Bundle extras, long pollFrequency) { + Bundle.setDefusable(extras, true); if (account == null) { throw new IllegalArgumentException("Account must not be null"); } @@ -706,7 +713,9 @@ public final class ContentService extends IContentService.Stub { } } + @Override public void removePeriodicSync(Account account, String authority, Bundle extras) { + Bundle.setDefusable(extras, true); if (account == null) { throw new IllegalArgumentException("Account must not be null"); } @@ -728,7 +737,7 @@ public final class ContentService extends IContentService.Stub { } } - + @Override public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName, ComponentName cname) { if (account == null) { @@ -750,6 +759,7 @@ public final class ContentService extends IContentService.Stub { } } + @Override public int getIsSyncable(Account account, String providerName) { return getIsSyncableAsUser(account, providerName, UserHandle.getCallingUserId()); } @@ -758,6 +768,7 @@ public final class ContentService extends IContentService.Stub { * If the user id supplied is different to the calling user, the caller must hold the * INTERACT_ACROSS_USERS_FULL permission. */ + @Override public int getIsSyncableAsUser(Account account, String providerName, int userId) { enforceCrossUserPermission(userId, "no permission to read the sync settings for user " + userId); @@ -777,6 +788,7 @@ public final class ContentService extends IContentService.Stub { return -1; } + @Override public void setIsSyncable(Account account, String providerName, int syncable) { if (TextUtils.isEmpty(providerName)) { throw new IllegalArgumentException("Authority must not be empty"); @@ -848,11 +860,11 @@ public final class ContentService extends IContentService.Stub { } } + @Override public boolean isSyncActive(Account account, String authority, ComponentName cname) { mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, "no permission to read the sync stats"); int userId = UserHandle.getCallingUserId(); - int callingUid = Binder.getCallingUid(); long identityToken = clearCallingIdentity(); try { SyncManager syncManager = getSyncManager(); @@ -866,6 +878,7 @@ public final class ContentService extends IContentService.Stub { } } + @Override public List<SyncInfo> getCurrentSyncs() { return getCurrentSyncsAsUser(UserHandle.getCallingUserId()); } @@ -874,6 +887,7 @@ public final class ContentService extends IContentService.Stub { * If the user id supplied is different to the calling user, the caller must hold the * INTERACT_ACROSS_USERS_FULL permission. */ + @Override public List<SyncInfo> getCurrentSyncsAsUser(int userId) { enforceCrossUserPermission(userId, "no permission to read the sync settings for user " + userId); @@ -892,6 +906,7 @@ public final class ContentService extends IContentService.Stub { } } + @Override public SyncStatusInfo getSyncStatus(Account account, String authority, ComponentName cname) { return getSyncStatusAsUser(account, authority, cname, UserHandle.getCallingUserId()); } @@ -900,6 +915,7 @@ public final class ContentService extends IContentService.Stub { * If the user id supplied is different to the calling user, the caller must hold the * INTERACT_ACROSS_USERS_FULL permission. */ + @Override public SyncStatusInfo getSyncStatusAsUser(Account account, String authority, ComponentName cname, int userId) { if (TextUtils.isEmpty(authority)) { @@ -911,7 +927,6 @@ public final class ContentService extends IContentService.Stub { mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, "no permission to read the sync stats"); - int callerUid = Binder.getCallingUid(); long identityToken = clearCallingIdentity(); try { SyncManager syncManager = getSyncManager(); @@ -930,6 +945,7 @@ public final class ContentService extends IContentService.Stub { } } + @Override public boolean isSyncPending(Account account, String authority, ComponentName cname) { return isSyncPendingAsUser(account, authority, cname, UserHandle.getCallingUserId()); } @@ -941,7 +957,6 @@ public final class ContentService extends IContentService.Stub { "no permission to read the sync stats"); enforceCrossUserPermission(userId, "no permission to retrieve the sync settings for user " + userId); - int callerUid = Binder.getCallingUid(); long identityToken = clearCallingIdentity(); SyncManager syncManager = getSyncManager(); if (syncManager == null) return false; @@ -959,6 +974,7 @@ public final class ContentService extends IContentService.Stub { } } + @Override public void addStatusChangeListener(int mask, ISyncStatusObserver callback) { long identityToken = clearCallingIdentity(); try { @@ -971,6 +987,7 @@ public final class ContentService extends IContentService.Stub { } } + @Override public void removeStatusChangeListener(ISyncStatusObserver callback) { long identityToken = clearCallingIdentity(); try { @@ -1027,6 +1044,7 @@ public final class ContentService extends IContentService.Stub { @Override public void putCache(String packageName, Uri key, Bundle value, int userId) { + Bundle.setDefusable(value, true); enforceCrossUserPermission(userId, TAG); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG); mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), @@ -1113,6 +1131,7 @@ public final class ContentService extends IContentService.Stub { } } + @Override public void binderDied() { synchronized (observersLock) { removeObserverLocked(observer); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 575de1664847..e6441ffe3839 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2247,11 +2247,6 @@ 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( |