Android security tags, read closely by Lightrion

CVE-2026-49882 AI-generated analysis

NFC tag reader/writer, Mifare Classic NDEF read (rw_mfc.cc): platform/system/nfc src/nfc/tags/rw_mfc.cc on Android 14/15, platform/packages/modules/Nfc libnfc-nci/src/nfc/tags/rw_mfc.cc on Android 16/17

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 (6 corrections). Verify against the commit before relying on it.

In rw_mfc_handle_read_op (Mifare Classic reader in the NFC stack), the fix saves ndef_length and ndef_start_pos just before rw_nfc_decodeTlv on the first block read. It then treats a decode failure, or any growth of ndef_length, as a failure and restores both fields, so an inflated length no longer stays in the control block where it bounds the copy into p_ndef_buffer.

Root cause

In rw_mfc_handle_read_op, on the first block of an NDEF read (p_mfc->work_offset == 0), rw_nfc_decodeTlv(data) parses TLV data from the tag and updates p_mfc->ndef_length and p_mfc->ndef_start_pos in the control block. Before the fix, the code saved only the length (saved_length, re-read from p_mfc->ndef_length on every call). If the decoded length was larger, it logged SafetyNet id 178725766 and set failed = true. It did not restore p_mfc->ndef_length or p_mfc->ndef_start_pos, so the inflated value stayed in p_mfc. That value is the bound of the copy loop (p_mfc->p_ndef_buffer[p_mfc->work_offset] = p[offset] while work_offset < ndef_length) and of the completion check (work_offset >= ndef_length). Because saved_length was taken from the already-inflated field on each call, the comparison would no longer catch the inflation on any later call.

How the fix works

Completeness

Behavior changes

Per major

Unknowns

Back to September 2026 · Findings