[PATCH] nfc: digital: check response length in ATR_RES completion
From: Noah Weinberger
Date: Sun Nov 08 2026 - 17:30:48 EST
Hello,
digital_tg_send_atr_res_complete() reads resp->data[0] and then
resp->data[offset] (offset 2, or 3 with the SOD byte) without any
resp->len check. A short next frame from the remote initiator reads
1-3 bytes past skb->len; with current drivers the read stays inside the
over-allocated response skb, so the impact is a KMSAN-visible
uninitialized read that at worst selects the wrong downstream handler
(both handlers re-validate their input).
The sibling digital_tg_recv_atr_or_sensf_req() checks resp->len >= 2
before touching data; the patch adds the equivalent checks here.
Affected version/commit: mainline fa4ad798f6f681031775266044ba1b0cf3c670bd (v7.4-rc1, 2026-11-07), net/nfc/digital_dep.c:1467-1487 (digital_tg_send_atr_res_complete).
Longstanding code.
This was found during an assisted (AI-supported) static source review of
mainline fa4ad798f6f681031775266044ba1b0cf3c670bd (v7.4-rc1, 2026-11-07); every code path cited below was re-verified by the
reporter against that tree. The patch below has NOT been compiled and has
NOT been runtime tested, and no reproducer was produced - the triggering
conditions are described above instead. Please treat this as a report for
verification rather than a battle-tested fix.
Reported-by: Noah Weinberger <noahweinberger2003@xxxxxxxxx>
---
diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c
index 968547c..b9b04db 100644
--- a/net/nfc/digital_dep.c
+++ b/net/nfc/digital_dep.c
@@ -1474,16 +1474,30 @@ static void digital_tg_send_atr_res_complete(struct nfc_digital_dev *ddev,
return;
}
+ if (resp->len < 1) {
+ digital_poll_next_tech(ddev);
+ goto exit;
+ }
+
offset = 2;
if (resp->data[0] == DIGITAL_NFC_DEP_NFCA_SOD_SB)
offset++;
+ if (resp->len < offset + 1) {
+ digital_poll_next_tech(ddev);
+ goto exit;
+ }
+
ddev->atn_count = 0;
if (resp->data[offset] == DIGITAL_CMD_PSL_REQ)
digital_tg_recv_psl_req(ddev, arg, resp);
else
digital_tg_recv_dep_req(ddev, arg, resp);
+
+return;
+exit:
+kfree_skb(resp);
}
static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,