CVE-2026-28667 AI-generated analysis
platform/system/nfc (Android 14/15) and platform/packages/modules/Nfc libnfc-nci (Android 16/17), NFC tag reader/writer, Type 5 Tag (ISO 15693) state machine in rw_t5t.cc
Adds a response-length check (length < p_i93->block_size) before three rw_i93_send_cmd_write_single_block calls in rw_t5t.cc, so a short tag response no longer leads to stale GKI buffer bytes being sent over RF in a WRITE_SINGLE_BLOCK command.
Root cause
In rw_t5t_sm_update_ndef and rw_t5t_sm_set_read_only, the code modifies block data in place through pointer p (for example *(p + xx) = ... and *(p + 1) |= I93_ICODE_CC_READ_ONLY) and then passes p to rw_i93_send_cmd_write_single_block. Per the commit message, this buffer is the response buffer, and nothing checked that the received length was at least block_size. If the response was shorter, stale GKI buffer slack was copied into the outgoing WRITE_SINGLE_BLOCK command and sent over RF. The material does not show the body of the send function; the block_size-sized copy is inferred from the commit message and the new guard. The commit message says this ports bounds checks from b/143109193, b/143155861 and b/143106535 to rw_t5t.cc.
How the fix works
- rw_t5t.cc:rw_t5t_sm_update_ndef, first site (after writing the first part of the NDEF into the block holding the TLV start, block_number = (ndef_tlv_start_offset + 1) / block_size): before rw_i93_send_cmd_write_single_block(block_number, p), the fix checks length < p_i93->block_size. If the check is true, it logs android_errorWriteLog(0x534e4554, "508389908") and calls rw_i93_handle_error(NFC_STATUS_FAILED) instead of sending.
- rw_t5t.cc:rw_t5t_sm_update_ndef, second site (block_number = rw_offset / block_size, followed by advancing rw_offset to the start of the next block): the same guard, log and error handling are added before rw_i93_send_cmd_write_single_block(block_number, p).
- rw_t5t.cc:rw_t5t_sm_set_read_only: after I93_ICODE_CC_READ_ONLY is set in *(p + 1), the same guard is added before rw_i93_send_cmd_write_single_block(0, p) (the CC block write).
- Each guard is inserted as an if / else if in front of the existing send call, so the existing failure branch (rw_i93_handle_error on send failure) is unchanged. rw_i93_send_cmd_write_single_block itself is not modified.
Completeness
- The fix covers the three rw_i93_send_cmd_write_single_block call sites in rw_t5t.cc that send the in-place modified buffer p. The material does not show the whole file, so other similar sites cannot be ruled out.
- In the visible context, the RW_I93_SUBSTATE_WRITE_NDEF path sets p = p_i93->p_update_data + p_i93->rw_length (line 575). Its payload therefore comes from the caller-supplied update data, not from the response buffer, and the fix does not touch it.
- The check is a single comparison, length < block_size. The material does not show how length is derived from p_resp, so it cannot confirm that the comparison is exact.
- The fix rejects and fails: it does not zero or truncate the buffer. A short response aborts the operation.
Behavior changes
- If a T5T tag response is shorter than block_size during an NDEF update or set-read-only operation, the operation now fails via rw_i93_handle_error(NFC_STATUS_FAILED) and no WRITE_SINGLE_BLOCK command is sent.
- A new log entry, android_errorWriteLog(0x534e4554, "508389908"), is emitted when this happens.
- Responses with length >= block_size follow the same path as before.
Per major
- Android 14: Same fix: platform/system/nfc f3a70c2a9415 in android-security-14.0.0_r29 adds three guards in src/nfc/tags/rw_t5t.cc. 8/8 patched lines present at android-security-14.0.0_r30.
- Android 15: Same fix: platform/system/nfc 620bfc1582b9 in android-security-15.0.0_r17, with identical hunks at different line offsets (571/749/831). 8/8 lines present at android-security-15.0.0_r18.
- Android 16: Same fix: platform/packages/modules/Nfc 144b34ba8906 in android-security-16.0.0_r8, file path libnfc-nci/src/nfc/tags/rw_t5t.cc, identical hunks. 8/8 lines present at android-security-16.0.0_r9.
- Android 17: Same fix: platform/packages/modules/Nfc 2ad8845ad77e in android-security-17.0.0_r1, same path and hunks as Android 16. 8/8 lines present at android-security-17.0.0_r2.
Unknowns
- How length is computed from p_resp in these functions (for example, whether it excludes the response flags byte).
- The body of rw_i93_send_cmd_write_single_block and exactly how many bytes it copies from p.
- Whether the earlier bugs (b/143109193, b/143155861, b/143106535) fixed the same pattern in rw_i93.cc. The material only says the checks were ported from them.
- Which substate the second rw_t5t_sm_update_ndef hunk belongs to, and its exact purpose. The case label is outside the shown context.
- Whether rw_t5t.cc has other call sites that send response-buffer data without a length check.