Thread (5 messages) flat view 5 messages, 2 authors, 1d ago
WARM1d

[PATCH net 2/2] nfc: digital: check resp length in digital_tg_send_atr_res_complete()

From: Liu Chao <hidden>
Date: 2026-09-12 13:24:36
Also in: lkml, oe-linux-nfc, stable
Subsystem: networking [general], nfc subsystem, the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Heidelberg, Linus Torvalds

digital_tg_send_atr_res_complete() reads resp->data[0] and
resp->data[offset] (offset 2 or 3) without checking resp->len.
The resp skb comes from the remote NFC peer, which controls its
length.  A short frame causes reads past the end of the received
data.

The downstream handlers (digital_tg_recv_psl_req, digital_tg_recv_dep_req)
each have their own length checks, so the consequence is a misdirected
dispatch on stale data rather than memory corruption.  Add the missing
check as hardening.

Fixes: 1c7a4c24fbfd ("NFC Digital: Add target NFC-DEP support")
Cc: stable@vger.kernel.org
Signed-off-by: Liu Chao <redacted>
---
 net/nfc/digital_dep.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c
index 6d8e662a3..5093b7b81 100644
--- a/net/nfc/digital_dep.c
+++ b/net/nfc/digital_dep.c
@@ -1467,16 +1467,19 @@ static void digital_tg_recv_psl_req(struct nfc_digital_dev *ddev, void *arg,
 static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
 					     void *arg, struct sk_buff *resp)
 {
-	int offset;
+	unsigned int offset;
 
 	if (IS_ERR(resp)) {
 		digital_poll_next_tech(ddev);
 		return;
 	}
 
-	offset = 2;
-	if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
-		offset++;
+	if (!resp->len)
+		goto bad_frame;
+
+	offset = (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB) ? 3 : 2;
+	if (resp->len <= offset)
+		goto bad_frame;
 
 	ddev->atn_count = 0;
 
@@ -1484,6 +1487,12 @@ static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
 		digital_tg_recv_psl_req(ddev, arg, resp);
 	else
 		digital_tg_recv_dep_req(ddev, arg, resp);
+
+	return;
+
+bad_frame:
+	kfree_skb(resp);
+	digital_poll_next_tech(ddev);
 }
 
 static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
-- 
2.50.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help