* Re: [PATCH net] nfc: llcp: fix SNL PDU size truncation in nfc_llcp_allocate_snl()
2026-11-11 9:59 [PATCH net] nfc: llcp: fix SNL PDU size truncation in nfc_llcp_allocate_snl() Linkui Xiao
@ 2026-11-11 10:02 ` netdev-bot+sinfo
2026-11-12 2:23 ` Linkui Xiao
2026-11-15 10:43 ` netdev-bot+sashiko
1 sibling, 1 reply; 4+ messages in thread
From: netdev-bot+sinfo @ 2026-11-11 10:02 UTC (permalink / raw)
To: Linkui Xiao
Cc: david, davem, edumazet, kuba, pabeni, horms, oe-linux-nfc,
netdev, linux-kernel, Linkui Xiao, Guikun Yang, stable
Hi!
This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:
- Whether the issue was actually triggered, or is only theoretical
(e.g. found by LLM and not proven at runtime). If it was triggered
please include the symptoms, like the stack trace or kernel messages.
Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.
The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH net] nfc: llcp: fix SNL PDU size truncation in nfc_llcp_allocate_snl()
2026-11-11 9:59 [PATCH net] nfc: llcp: fix SNL PDU size truncation in nfc_llcp_allocate_snl() Linkui Xiao
2026-11-11 10:02 ` netdev-bot+sinfo
@ 2026-11-15 10:43 ` netdev-bot+sashiko
1 sibling, 0 replies; 4+ messages in thread
From: netdev-bot+sashiko @ 2026-11-15 10:43 UTC (permalink / raw)
To: xiaolinkui
Cc: david, davem, edumazet, kuba, pabeni, horms, oe-linux-nfc,
netdev, linux-kernel, xiaolinkui, yangguikun19, stable
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 0 (1) · Medium: 1 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] The commit message names the wrong trigger and leaves out the
real one.
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but the patch
makes it easier to reach.
--
nfc: llcp: fix SNL PDU size truncation in nfc_llcp_allocate_snl()
This commit changes the size accumulator in nfc_llcp_allocate_snl() from
u16 to size_t, so the SNL PDU allocation size can no longer wrap before
alloc_skb(). The commit message says the overflow comes from
nfc_genl_llc_sdreq() building many SDREQ TLVs out of a netlink request.
Link: https://lore.kernel.org/netdev/tencent_634C55A23C7CCCA3985283BFED46A69C9E09@qq.com/
> nfc_genl_llc_sdreq() walks the nested NFC_ATTR_LLC_SDP attributes of a
> GENL_ADMIN_PERM request, builds one SDREQ TLV per attribute and sums
> their lengths into the size_t tlvs_len. Each URI is capped at
> U8_MAX - 4 bytes by nfc_sdp_genl_policy, so every TLV fits in its u8
> tlv_len, but nothing caps the number of attributes, so tlvs_len can
> exceed U16_MAX.
[Severity: Medium]
Can this netlink path actually wrap the u16?
nfc_genl_llc_sdreq() only walks a single attribute:
nla_for_each_nested(attr, info->attrs[NFC_ATTR_LLC_SDP], rem) {
NFC_ATTR_LLC_SDP is one NLA_NESTED attribute, and its nla_len is a
__u16, so the nested payload is at most 65531 bytes.
Each entry costs at least 8 bytes of nest and URI attribute headers plus
NLA_ALIGN(uri_len), and it produces a TLV of only uri_len + 3 bytes. With
uri_len = 251 that comes to about 64014 TLV bytes at most. The
LLCP_HEADER_SIZE, NFC_HEADER_SIZE, tx_headroom and tx_tailroom that
nfc_llcp_allocate_snl() adds are small for the in-tree drivers.
The path that does look able to wrap is the remote SDRES one:
nfc_llcp_recv_snl()
nfc_llcp_build_sdres_tlv() /* 4 bytes per 3-byte SDREQ TLV */
nfc_llcp_send_snl_sdres(local, &llc_sdres_list, sdres_tlvs_len)
nfc_llcp_allocate_snl()
A peer in NFC range can send one SNL PDU packed with 3-byte SDREQ TLVs
(type, len=1, tid). sdres_tlvs_len then grows to about 4/3 of the frame
size.
Neither nci_add_rx_data_frag() (via skb_cow_head()) nor
digital_recv_dep_data_gather() (via skb_copy_expand()) caps the
reassembled frame. An SNL PDU of about 49 KB would therefore wrap the old
u16 size and hit skb_over_panic() in nfc_llcp_send_snl_sdres().
The code change fixes both senders, since they share
nfc_llcp_allocate_snl(). Could the commit message describe the SDRES path
that an unprivileged remote peer can trigger, instead of the
GENL_ADMIN_PERM netlink path? As written, it reads as if the bug needs
CAP_NET_ADMIN to trigger.
> diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
> index 80a00938c8696..0a3d66e6cd59f 100644
> --- a/net/nfc/llcp_commands.c
> +++ b/net/nfc/llcp_commands.c
> @@ -542,7 +542,7 @@ static struct sk_buff *nfc_llcp_allocate_snl(struct nfc_llcp_local *local,
> {
> struct sk_buff *skb;
> struct nfc_dev *dev;
> - u16 size = 0;
> + size_t size = 0;
[Severity: High]
This is a pre-existing issue, but now that size no longer wraps, does
nfc_llcp_recv_snl() leak the llc_sdres_list entries when alloc_skb() fails
here?
nfc_llcp_send_snl_sdres() returns before the loop that frees the entries:
net/nfc/llcp_commands.c:nfc_llcp_send_snl_sdres() {
skb = nfc_llcp_allocate_snl(local, tlvs_len);
if (IS_ERR(skb))
return PTR_ERR(skb);
hlist_for_each_entry_safe(sdp, n, tlv_list, node) {
skb_put_data(skb, sdp->tlv, sdp->tlv_len);
hlist_del(&sdp->node);
nfc_llcp_free_sdp_tlv(sdp);
}
...
}
nfc_llcp_recv_snl() ignores the return value, and the list head is on its
stack:
net/nfc/llcp_core.c:nfc_llcp_recv_snl() {
HLIST_HEAD(llc_sdres_list);
...
if (!hlist_empty(&llc_sdres_list))
nfc_llcp_send_snl_sdres(local, &llc_sdres_list, sdres_tlvs_len);
}
Each SDREQ TLV from the peer leaves behind a struct nfc_llcp_sdp_tlv and
its 4-byte tlv buffer. That is about 72 bytes for every 3 bytes on the
wire.
Before this change, a frame that needed more than 64 KiB wrapped size and
panicked. Now alloc_skb() gets the full size, about 4/3 of the frame.
That allocation can fail for costly orders under fragmentation. It always
fails once the request is above MAX_PAGE_ORDER: on x86-64 with 4 KiB
pages, that is an SDRES over 4 MiB, from an SNL PDU of about 3 MiB.
Frame reassembly has no cap, so one such frame would leak around 1M
entries, roughly 72 MB. Repeated frames could drive the system to OOM.
The same leak happens when local->dev is NULL and nfc_llcp_allocate_snl()
returns -ENODEV.
Should the tlv_list entries be freed on this error path, either in
nfc_llcp_send_snl_sdres() or in its caller?
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261111095907.3366028-1-xiaolinkui%40126.com
^ permalink raw reply [flat|nested] 4+ messages in thread