Android security tags, read closely by Lightrion

CVE-2025-22429 AI-generated analysis

platform/frameworks/base, core/java/android/os (BaseBundle / Parcel lazy unparceling)

AI-generated: written from the bulletin and the fixing diffs by claude-fable-5-1, then checked against the code by claude-opus-5-5 (7 corrections). Verify against the commit before relying on it.

Changes Parcel.readArrayMap to report the number of LazyValue entries through an int[] out-parameter that is updated as each value is read. BaseBundle.initializeFromParcelLocked therefore sees the correct count in its finally block even when readArrayMap throws partway, and no longer recycles a Parcel that LazyValue entries still reference.

Root cause

In BaseBundle.initializeFromParcelLocked, the lazy value count came from the return value of Parcel.readArrayMap: `numLazyValues = parcelledData.readArrayMap(...)`. readArrayMap adds entries to the map one by one and returns the count only at the end. If it threw after some LazyValue objects had already been added to `map`, the assignment never happened and numLazyValues stayed 0. The finally block runs regardless. With ownsParcel true and numLazyValues == 0, it called recycleParcel(parcelledData), set mLazyValues = 0 and installed mMap = map, so the map could keep LazyValue entries tied to the recycled Parcel. In the non-defuse path (sShouldDefuse false) the map is not erased before the exception propagates.

How the fix works

Completeness

Behavior changes

Per major

Unknowns

Back to April 2025 · Findings