From c4fd93e43b1210164cdaa5a9d895f9666e108a66 Mon Sep 17 00:00:00 2001 From: Tyler Gunn Date: Tue, 12 Sep 2017 13:39:38 -0700 Subject: Fix ImsCallProfile parceling and add protection for invalid parcelables. Two things: 1. The writeToParcel and readFromParcel in the ImsCallProfile never worked; they were not parceling the Bundle properly. 2. Ensuring on writeToParcel that invalid Bundle contents are removed and not sent across a Binder interface. The existing Bundle.filterValues method accomplishes this by ensuring only primitive types and android.* namespace parcelables are included in the Bundle. We use this to ensure that when the ImsCallProfile instances cross the binder call boundary, package-local Parcelables don't cause the Bundle to be invalidated when unmarshaled in a place where the pacakge-local parcelable is not available. Test: Manual, also wrote new unit tests Bug: 65562929 Change-Id: Iea982d14a053414b9a4daba998c021c61902119d --- telephony/java/com/android/ims/ImsCallProfile.java | 55 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java index 36abfc9d288e..489c208a0d46 100644 --- a/telephony/java/com/android/ims/ImsCallProfile.java +++ b/telephony/java/com/android/ims/ImsCallProfile.java @@ -19,7 +19,9 @@ package com.android.ims; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import android.telecom.VideoProfile; +import android.util.Log; import com.android.internal.telephony.PhoneConstants; @@ -216,6 +218,29 @@ public class ImsCallProfile implements Parcelable { public int mServiceType; public int mCallType; public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE; + + /** + * Extras associated with this {@link ImsCallProfile}. + *

+ * Valid data types include: + *

+ *

+ * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across + * a {@link android.os.Binder}. + */ public Bundle mCallExtras; public ImsStreamMediaProfile mMediaProfile; @@ -315,16 +340,17 @@ public class ImsCallProfile implements Parcelable { @Override public void writeToParcel(Parcel out, int flags) { + Bundle filteredExtras = maybeCleanseExtras(mCallExtras); out.writeInt(mServiceType); out.writeInt(mCallType); - out.writeParcelable(mCallExtras, 0); + out.writeBundle(filteredExtras); out.writeParcelable(mMediaProfile, 0); } private void readFromParcel(Parcel in) { mServiceType = in.readInt(); mCallType = in.readInt(); - mCallExtras = in.readParcelable(null); + mCallExtras = in.readBundle(); mMediaProfile = in.readParcelable(null); } @@ -464,6 +490,31 @@ public class ImsCallProfile implements Parcelable { return VideoProfile.isVideo(getVideoStateFromCallType(mCallType)); } + /** + * Cleanses a {@link Bundle} to ensure that it contains only data of type: + * 1. Primitive data types (e.g. int, bool, and other values determined by + * {@link android.os.PersistableBundle#isValidType(Object)}). + * 2. Other Bundles. + * 3. {@link Parcelable} objects in the {@code android.*} namespace. + * @param extras the source {@link Bundle} + * @return where all elements are valid types the source {@link Bundle} is returned unmodified, + * otherwise a copy of the {@link Bundle} with the invalid elements is returned. + */ + private Bundle maybeCleanseExtras(Bundle extras) { + if (extras == null) { + return null; + } + + int startSize = extras.size(); + Bundle filtered = extras.filterValues(); + int endSize = filtered.size(); + if (startSize != endSize) { + Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were " + + "removed - only primitive types and system parcelables are permitted."); + } + return filtered; + } + /** * Determines if a video state is set in a video state bit-mask. * -- cgit v1.2.3-59-g8ed1b