CVE-2025-26455 AI-generated analysis
platform/frameworks/av, media/ndk (libmediandk AMediaCodec wrapper)
Makes the pointer/size pairs returned by the NDK AMediaCodec_getInputBuffer and AMediaCodec_getOutputBuffer APIs consistent (input: base pointer with capacity; output: data pointer with actual size) and sets the offset reported by AMediaCodec_dequeueOutputBuffer to 0 because the output pointer is already offset.
Root cause
In media/ndk/NdkMediaCodec.cpp, AMediaCodec_getInputBuffer returned abuf->data() while reporting *out_size = abuf->capacity(); per the commit message this erroneously considered the buffer offset and could result in a smaller input buffer being returned and client confusion. AMediaCodec_getOutputBuffer returned data() but reported capacity() rather than size(), so per the commit message the reported size included padding after the output buffer. AMediaCodec_dequeueOutputBuffer copied the codec's internal offset into AMediaCodecBufferInfo.offset even though, per the fix comment, the output buffer address is already offset in AMediaCodec_getOutputBuffer, so a client honoring info.offset would apply it twice. The pattern existed in both the asynchronous (mCodec->getInputBuffer/getOutputBuffer) and synchronous (getInputBuffers/getOutputBuffers vector) branches.
How the fix works
- media/ndk/NdkMediaCodec.cpp:AMediaCodec_getInputBuffer (async branch using mCodec->getInputBuffer): return abuf->base() instead of abuf->data(), keeping *out_size = abuf->capacity(). A comment explains the input buffer is empty when handed out and the offset is set at queueInputBuffer time.
- media/ndk/NdkMediaCodec.cpp:AMediaCodec_getInputBuffer (sync branch using mCodec->getInputBuffers vector): return abufs[idx]->base() instead of abufs[idx]->data().
- media/ndk/NdkMediaCodec.cpp:AMediaCodec_getOutputBuffer (async branch): *out_size = abuf->size() instead of abuf->capacity(); pointer stays abuf->data().
- media/ndk/NdkMediaCodec.cpp:AMediaCodec_getOutputBuffer (sync vector branch): *out_size = abufs[idx]->size() instead of abufs[idx]->capacity().
- media/ndk/NdkMediaCodec.cpp:AMediaCodec_dequeueOutputBuffer: on OK, info->offset = 0 instead of the offset returned by mCodec->dequeueOutputBuffer, since AMediaCodec_getOutputBuffer already returns the offset pointer; info->size, flags and presentationTimeUs unchanged.
- media/ndk/include/media/NdkMediaCodec.h: documentation only. Adds notes on AMediaCodec_getOutputBuffer and AMediaCodec_dequeueOutputBuffer describing behavior at or before API level 35 (out_size invalid, offset invalid) versus after, and removes mentions of non-existent AMediaCodec_getInputBuffers/AMediaCodec_getOutputBuffers from the asynchronous-callback doc comment.
Completeness
- Covers both the asynchronous single-buffer paths and the synchronous vector paths of AMediaCodec_getInputBuffer and AMediaCodec_getOutputBuffer, plus the offset reported by AMediaCodec_dequeueOutputBuffer.
- For input buffers the fix changes the pointer (base()) rather than the size, so out_size still reports capacity().
- For output buffers the fix changes only the size (size()) and keeps the data() pointer; the internal offset is not exposed to the client.
- The diff does not touch any other place that might fill an AMediaCodecBufferInfo (for example an asynchronous output-available callback path); the material does not show whether such a path reports an offset.
- No validation is added inside libmediandk. Clients that used info.size from AMediaCodec_dequeueOutputBuffer rather than out_size (as ImsMediaAudioSource::dequeueOutputBuffer does, per index search) were already using the payload size.
Behavior changes
- AMediaCodec_getInputBuffer now returns the buffer base address; if the internal offset is nonzero this pointer differs from the pre-fix value (same reported capacity).
- AMediaCodec_getOutputBuffer now reports size() instead of capacity(); clients relying on out_size for output buffers will see a smaller value.
- AMediaCodec_dequeueOutputBuffer always sets AMediaCodecBufferInfo.offset to 0.
- No new error codes or return paths; apart from the value changes above, the remaining changes are header documentation.
Per major
- Android 14: same fix: platform/frameworks/av e28ca0c3d70c in android-security-14.0.0_r21 (cherry-pick of d69fe7b73a0e, Change-Id I6bbd9b85023aef56a608362afde0662d3df7284a); identical hunks to the 15 commit; at android-security-14.0.0_r29 all 8 patched lines are present.
- Android 15: same fix: platform/frameworks/av a5c1d4f8d6d5 in android-security-15.0.0_r9, identical diff (same blob ids b230df5179..240848096a as 14); at android-security-15.0.0_r17 all 8 patched lines are present.
- Android 16: same fix: original commit d69fe7b73a0e in android-16.0.0_r2; identical content, only hunk line numbers differ (NdkMediaCodec.cpp d22a5ba147..62ef6118ca); at android-security-16.0.0_r8 all 8 patched lines are present.
- Android 17: not affected per the bulletin (not listed); the patched region is fully present at android-security-17.0.0_r1.
Unknowns
- Which codec implementations or buffer allocators produce a nonzero internal offset or capacity larger than size for NDK-visible buffers.
- Whether the old pointer/size mismatch could lead clients to access memory outside the buffer; the material describes only incorrect sizes and client confusion.
- Whether any asynchronous callback path in NdkMediaCodec.cpp also reports AMediaCodecBufferInfo.offset; the diff does not touch such a path.
- The concrete EoP scenario behind the bulletin's High rating.