mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net] nfc: nci: avoid unbounded skb allocation when max_pkt_payload_len is zero
@ 2026-09-13 10:13 Liu Chao
  2026-09-14 11:08 ` netdev-bot+sashiko
  0 siblings, 1 reply; 3+ messages in thread
From: Liu Chao @ 2026-09-13 10:13 UTC (permalink / raw)
  To: David Heidelberg
  Cc: davem, edumazet, kuba, pabeni, horms, Ilan Elias,
	John W . Linville, oe-linux-nfc, netdev, linux-kernel, Liu Chao,
	stable

nci_queue_tx_data_frags() uses conn_info->max_pkt_payload_len as the
fragment size.  When that value is zero, frag_len is always zero and
total_len never decreases.  The loop then allocates skbs without bound:
none of them are freed inside the loop, they accumulate on frags_q, and
there is no cond_resched() in the loop body.  A single sendmsg() can
therefore consume all allocatable memory, and on CONFIG_PREEMPT_NONE it
occupies the CPU long enough to trip the softlockup watchdog:

  watchdog: BUG: soft lockup - CPU#3 stuck for 26s! [kworker/3:1:57]
  Workqueue: events rawsock_tx_work [nfc]
  Call Trace:
   nci_send_data+0x1ca/0x6b0 [nci]
   nci_transceive+0xbb/0x170 [nci]
   rawsock_tx_work+0xb5/0x1a0 [nfc]

max_pkt_payload_len is taken verbatim from controller-supplied fields,
with no check for zero:

  ntf.c: conn_info->max_pkt_payload_len = ntf.max_data_pkt_payload_size;
  rsp.c: conn_info->max_pkt_payload_len = rsp->max_ctrl_pkt_payload_len;

Reject the zero value in the fragmentation path rather than at the
assignment sites.  nci_queue_tx_data_frags() is the only place that
loops, and nci_send_data() takes the non-fragmenting branch only for
skb->len <= max_pkt_payload_len, which for a zero limit means empty
skbs alone.  Validating on assignment would not be sufficient either,
because nci_rf_disc_rsp_packet() allocates ndev->rf_conn_info with
devm_kzalloc(), so max_pkt_payload_len is already zero before any
notification arrives.

No legitimate configuration is known to be affected.  Where the NCI
spec does mandate a zero Max Data Packet Payload Size -- the NFCEE
Direct RF Interface -- nci_rf_intf_activated_ntf_packet() takes the
"goto listen" shortcut, bypassing the assignment entirely.

Reproduced with CONFIG_NFC_VIRTUAL_NCI by injecting an
RF_INTF_ACTIVATED_NTF with max_data_pkt_payload_size set to 0 and then
sending a data frame on an AF_NFC SEQPACKET socket.

Fixes: 6a2968aaf50c ("NFC: basic NCI protocol implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Liu Chao <liuc63@xiaopeng.com>
---
 net/nfc/nci/data.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
index 4253edea5..b549cef7d 100644
--- a/net/nfc/nci/data.c
+++ b/net/nfc/nci/data.c
@@ -114,6 +114,11 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
 		goto exit;
 	}
 
+	if (!conn_info->max_pkt_payload_len) {
+		rc = -EPROTO;
+		goto exit;
+	}
+
 	__skb_queue_head_init(&frags_q);
 
 	while (total_len) {

base-commit: e6b6078ea1731b05b3b552497b3bce4bf8b014ae
-- 
2.50.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-17 13:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-13 10:13 [PATCH net] nfc: nci: avoid unbounded skb allocation when max_pkt_payload_len is zero Liu Chao
2026-09-14 11:08 ` netdev-bot+sashiko
2026-09-17 13:24   ` Simon Horman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®