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.

Zero checking a block against the end of a tray held by Tux

Declared → received → check. Check length against the received packet.

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.