CVE-2024-34723 AI-generated analysis
platform/frameworks/base, media session (android.media.session.ParcelableListBinder, com.android.server.media.MediaSessionRecord)
ParcelableListBinder now takes the expected element Class and only adds deserialized Parcelables that are assignable to it, and MediaSessionRecord.getBinderForSetQueue passes QueueItem.class, so non-QueueItem Parcelable objects are no longer accepted into the media session queue list.
Root cause
ParcelableListBinder.onTransact read each list element with data.readParcelable(null) and added it to the List<T> without checking its runtime type. Because of generic erasure, any Parcelable class the caller wrote was accepted. MediaSessionRecord.getBinderForSetQueue returns such a binder, and its consumer stores the received list in mQueue, which is expected to hold QueueItem. A caller that transacts with this binder directly could therefore put non-QueueItem Parcelables into mQueue (the commit cites malicious apps calling it directly via reflection with incompatible items, b/317048338). The commit title describes the vulnerability as allowing apps to start from the background. The bulletin rates it High EoP.
How the fix works
- media/java/android/media/session/ParcelableListBinder.java: the constructor ParcelableListBinder(Class<T> listElementsClass, Consumer<List<T>> consumer) stores the expected element class in the new field mListElementsClass.
- media/java/android/media/session/ParcelableListBinder.java:onTransact: each element is read into an Object via data.readParcelable(null). It is added to mList (cast to T) only if mListElementsClass.isAssignableFrom(object.getClass()). Items that do not match are skipped, but i is still incremented, so the mCount / END_OF_PARCEL framing is unchanged.
- services/core/java/com/android/server/media/MediaSessionRecord.java:getBinderForSetQueue: builds the binder with QueueItem.class, so only QueueItem (or subclasses) reach mQueue before MSG_UPDATE_QUEUE is posted.
Completeness
- Covers the single instantiation shown in the material (MediaSessionRecord.getBinderForSetQueue). Because the constructor signature changed, any other ParcelableListBinder user that was not updated would fail to compile rather than stay unchecked.
- The check runs after data.readParcelable(null) has already created whatever Parcelable class the caller named. The fix filters the result; it does not restrict which classes get deserialized.
- The check calls object.getClass() without a null guard. A null element, which was previously added to the list as null, would now throw NullPointerException inside onTransact.
- Only the element type is validated. This change does not inspect the contents of a QueueItem.
Behavior changes
- Elements whose runtime class is not assignable to the declared element class are silently dropped from the delivered list.
- A null element in the parcel would now cause a NullPointerException in ParcelableListBinder.onTransact instead of being added to the list.
- The ParcelableListBinder constructor signature changed (@hide class): callers must pass Class<T>.
Per major
- Android 14: same fix: commit 9c8c745df069 in android-security-14.0.0_r10 (cherry-pick of c5fc8ea92c0a). At android-security-14.0.0_r29, 7/8 lines of the patched region are present.
- Android 15: not affected per the bulletin. At android-security-15.0.0_r17, 7/8 lines of the patched region are present.
- Android 16: not affected per the bulletin. At android-security-16.0.0_r8, 7/8 lines of the patched region are present.
- Android 17: not affected per the bulletin. At android-security-17.0.0_r1, 7/8 lines of the patched region are present.
Unknowns
- The material does not show which consumer of mQueue turns the injected Parcelable into the background-start EoP.
- The per-major facts do not show whether the fix was also applied to the 12/12L/13 branches listed as affected.
- The material does not show why 7/8 lines rather than 8/8 of the patched region are present at the latest tags.