[PATCH] nfc: digital: fix stack out-of-bounds write in digital_in_recv_sensf_res()

From: Naveed Khan

Date: Tue Jul 07 2026 - 16:18:11 EST


digital_in_recv_sensf_res() handles the SENSF_RES response received from a
remote NFC-F device. It validates only a lower bound on the frame length
(DIGITAL_SENSF_RES_MIN_LENGTH == 17), strips the leading length byte with
skb_pull(), and then copies resp->len bytes into the fixed-size stack field
target.sensf_res, which is NFC_SENSF_RES_MAXSIZE (18) bytes:

if (resp->len < DIGITAL_SENSF_RES_MIN_LENGTH) {
rc = -EIO;
goto exit;
}
...
skb_pull(resp, 1);
...
memcpy(target.sensf_res, sensf_res, resp->len);
target.sensf_res_len = resp->len;

resp->len is fully controlled by the peer and is never bounded from above, so
a device that returns a SENSF_RES frame longer than the maximum valid frame
overflows target.sensf_res on the stack with attacker-controlled bytes.

The sibling parsers in the same file use exact length checks
(digital_in_recv_sensb_res, digital_in_recv_iso15693_inv_res and
digital_in_recv_sel_res); only this path copies a variable, unbounded length.

Reject frames whose payload does not fit in target.sensf_res before the copy,
consistent with the existing error handling in the function.

Signed-off-by: Naveed Khan <naveed@xxxxxxxxxxxxxx>
---
diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c
index ae63c5eb06..d6e351d642 100644
--- a/net/nfc/digital_technology.c
+++ b/net/nfc/digital_technology.c
@@ -774,6 +774,11 @@ static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg,

skb_pull(resp, 1);

+ if (resp->len > sizeof(target.sensf_res)) {
+ rc = -EIO;
+ goto exit;
+ }
+
memset(&target, 0, sizeof(struct nfc_target));

sensf_res = (struct digital_sensf_res *)resp->data;
--
2.52.0