Skip to content

NFC: Fix Type 4 Tag writes that start inside the NLEN field - #574

Open
Endika wants to merge 3 commits into
Next-Flip:devfrom
Endika:fix-t4t-write-offset
Open

Endika wants to merge 3 commits into
Next-Flip:devfrom
Endika:fix-t4t-write-offset

Conversation

@Endika

@Endika Endika commented Jul 28, 2026 •

Copy link
Copy Markdown

Description

In type_4_tag_listener_iso_write(), a write that starts inside the two-byte NLEN field consumes write_len = sizeof(uint16_t) - offset bytes for that field. The payload pointer is then advanced by offset instead:

const uint8_t write_len = sizeof(uint16_t) - offset;
ndef_file_len_new = bit_lib_bytes_to_num_be(data, write_len);
offset = sizeof(uint16_t);
data += offset;      // offset was just reassigned to 2
lc -= write_len;

offset has already been reassigned to sizeof(uint16_t) on the line above, so data always moves forward by 2 regardless of how much was actually consumed.

With offset == 0 the two agree (write_len is 2), which is why this goes unnoticed. With offset == 1 only one byte belongs to NLEN, so:

  • the NDEF payload is taken starting one byte too far in, shifting the written content by one, and
  • lc was only reduced by 1, so the copy runs one byte past the end of the reader's APDU data.

offset comes straight from the command header (offset = (p1 << 8) + p2), so a reader only has to send P1 = 0x00, P2 = 0x01 to reach it.

Fix

Advance by the number of bytes actually consumed:

data += write_len;

Behaviour at offset == 0 is unchanged, since write_len is 2 there.

Additional fixes ported from unleashed

While reviewing the fix above in DarkFlippers/unleashed-firmware#1049, @mishamyte found four more ways a reader can crash a Flipper emulating a Type 4 Tag and fixed them in DarkFlippers/unleashed-firmware#1051, stacked on top. This repo carries the same code, so it carries the same crashes. Both of his commits are included here with their original authorship.

Verification

./fbt firmware_all builds clean (f7-firmware-C).

This file is byte-identical between this repo and DarkFlippers/unleashed-firmware (blob 7da6fadc), and the fixed file is likewise identical to the one in DarkFlippers/unleashed-firmware#1049 (blob 84ccfb9b) — so this is the same change, not a re-derivation.

@Endika
Endika force-pushed the fix-t4t-write-offset branch from 3157929 to 8b395b1 Compare September 10, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants