CVE-2026-49879 AI-generated analysis
platform/system/nfc (Android 14/15) and platform/packages/modules/Nfc libnfc-nci (Android 16/17), Type 3 Tag reader/writer (src/nfc/tags/rw_t3t.cc)
Widens block_id to uint32_t and recomputes the block-range bounds checks and loop limits in uint32_t in rw_t3t_send_next_ndef_update_cmd and rw_t3t_send_next_ndef_check_cmd (Type 3 Tag NDEF update/check), and frees the GKI command buffer when the bounds check fails.
Root cause
In rw_t3t_send_next_ndef_update_cmd and rw_t3t_send_next_ndef_check_cmd, the block-list loop used a uint16_t block_id running from first_block_to_write/first_block_to_read up to first + count. The guard before the loop (`count > UINT16_MAX - first`, logged as "Heap out-of-bounds" with tag 508389055) returned on error without freeing p_cmd_buf. The commit message says the range calculations and loop conditions needed to be done in uint32_t to prevent integer overflow. The material does not show the exact overflow condition that remained with the earlier guard in place, because the loop body and the derivation of the block values are not shown.
How the fix works
- src/nfc/tags/rw_t3t.cc:rw_t3t_send_next_ndef_update_cmd: block_id moves from a uint16_t declaration to uint32_t (declared alongside timeout), so the loop index can hold 0x10000 without wrapping.
- src/nfc/tags/rw_t3t.cc:rw_t3t_send_next_ndef_update_cmd: the bounds check becomes `(uint32_t)first_block_to_write + ndef_blocks_to_write > 0x10000`. The sum is computed in 32 bits, and the range may end at block 65535 inclusive. On failure, GKI_freebuf(p_cmd_buf) is now called before logging and returning.
- src/nfc/tags/rw_t3t.cc:rw_t3t_send_next_ndef_update_cmd: the loop condition becomes `block_id < ((uint32_t)first_block_to_write + ndef_blocks_to_write)`.
- src/nfc/tags/rw_t3t.cc:rw_t3t_send_next_ndef_check_cmd: the same changes for the check path. block_id is widened to uint32_t, the check becomes `(uint32_t)first_block_to_read + cur_blocks_to_read > 0x10000` with GKI_freebuf(p_cmd_buf) on failure, and the loop limit is cast to uint32_t.
- The android_errorWriteLog tag in both error paths stays "508389055" rather than this commit's bug 503544522.
Completeness
- Both Type 3 Tag NDEF block-list builders in the diff (update and check) get the same three-part change: wider index, 32-bit range check, and buffer free.
- The new guard accepts one more block than the old one: a sum of exactly 0x10000 was rejected before and is now accepted. The widened uint32_t block_id lets the loop end at 65536.
- The fix does not change how first_block_to_write/first_block_to_read or the block counts are derived, or how p_cmd_buf is sized. Other command builders in rw_t3t.cc are not touched and are not shown in the material.
Behavior changes
- When a block range is rejected, the GKI command buffer is now released instead of leaked. The function still logs "Heap out-of-bounds" and takes the same error return.
- Block ranges ending exactly at 0x10000 (last block 65535) are now accepted rather than rejected.
- No new error codes or API changes are visible in the diff.
Per major
- Android 14: Same fix: platform/system/nfc c1fa4599a13e in android-security-14.0.0_r29, src/nfc/tags/rw_t3t.cc (Cherrypick-From / Merged-In of Change-Id I8daf5de0b16c0f17a8c0b01f65359cde2d302bff). 7 of 8 patched-region lines are present at that tag.
- Android 15: Same fix: platform/system/nfc 78dd34a6a026 in android-security-15.0.0_r17, same hunks in src/nfc/tags/rw_t3t.cc. 7 of 8 patched-region lines are present at that tag.
- Android 16: Same fix in a different location: platform/packages/modules/Nfc 92d884176dcd in android-security-16.0.0_r8, libnfc-nci/src/nfc/tags/rw_t3t.cc, same hunks. 7 of 8 patched-region lines are present at that tag.
- Android 17: Same fix in a different location: platform/packages/modules/Nfc 442e948e4be2 in android-security-17.0.0_r1, libnfc-nci/src/nfc/tags/rw_t3t.cc, same hunks. 7 of 8 patched-region lines are present at that tag.
Unknowns
- How first_block_to_write/first_block_to_read and the block counts are derived (for example, from tag-provided NDEF attribute data), and how large p_cmd_buf is. The surrounding function bodies are not in the material.
- Which overflow condition remained with the earlier guard in place: the diff alone does not show a wrap that the old guard allowed.
- Whether the main impact addressed by this CVE is the overflow handling or the command-buffer leak on the error path.
- Why the bulletin rates this as Critical EoP.
- Which line of the patched region differs in each latest security tag (7/8 lines present).
- No test is included (Test: Manual).