A length field the NFC parser trusted
3 min read

Updated

A length field the NFC parser trusted

Linux's NFC service-discovery parser needed checks against the received packet and against each message type's minimum length. The defect illustrates why declared lengths are not buffer bounds.

The NFC service-discovery parser read lengths from an incoming message without consistently checking them against the packet that contained it.

A length field describes what the sender claims to have supplied. The buffer length describes what actually arrived. A parser has to compare the two before it reads.

In Linux’s LLCP service-discovery path, that comparison was incomplete. A separate subtraction also assumed that a request contained at least one byte.

Follow one entry through the parser

LLCP is a link-layer protocol used for NFC peer communication. Its Service Name Lookup messages contain type-length-value entries, usually called TLVs.

Each entry starts with a type and a declared value length. The parser then interprets the value according to the type.

The function nfc_llcp_recv_snl() needed to establish several conditions before advancing:

  • enough packet data remains for the TLV header;
  • the declared value fits within the remaining packet;
  • the value is long enough for the selected message type.

Checking only one of those conditions leaves the others open.

For a service-discovery request, the value contains a transaction identifier followed by the service name. Calculating the name length as length - 1 assumes the identifier exists. A zero-length request violates that assumption before the parser reaches the name.

Packet entries with one extending beyond the valid boundary

Bound the walk before interpreting the value

The submitted fix bounds parsing against the end of the socket buffer and checks the type-specific lengths before using them. A service-discovery request must include its transaction identifier; a service-discovery response has a fixed expected length.

That order matters. First establish that the bytes exist. Then interpret what they mean.

The patch reached Linus’s mainline tree as f4c7f37f — rebased on merge from the maintainer-tree commit ed85d4cbbfaa, following review by NFC maintainer David Heidelberg and Simon Horman. On 2026-09-12 it was queued to the 6.6, 6.12, 6.18 and 7.2 stable trees. A queued stable patch is not a released kernel: presence in a tree should not be read as proof that a particular distribution has shipped the fix.

This SNL parsing issue is also distinct from the other NFC length-check fixes in our kernel contribution roundup. Similar subsystem names don’t make them one finding.

Keep exposure separate from source presence

The code’s presence in a kernel tree doesn’t establish that every device exposes it. A practical attack depends on the kernel configuration, NFC hardware and driver support, and whether the relevant peer-protocol path is active.

Short-range NFC communication is also different from an internet-reachable service. The original article’s claims about every kernel and anyone standing next to a phone were broader than the evidence supported.

The source-level defect is the unchecked parsing boundary. A claim about a crash, a leak to the sender, or a particular device needs evidence for that additional consequence.

Why this is useful to investigate statically

A source review can ask where a loop ends and how each read is bounded without first building a complete radio test environment. It can identify an assumption that deserves a patch or a targeted reproducer.

Execution still matters when describing impact. Static analysis, maintainer acceptance, and a device-level reproduction answer different questions.

This parser provides a compact review rule: every length read from a message must be checked against both the available bytes and the format’s own minimum requirements.