From: "Tianchu Chen" <tianchu.chen@linux.dev>
To: david@ixit.cz, sameo@linux.intel.com, shikha.singh@st.com
Cc: oe-linux-nfc@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [PATCH] nfc: st95hf: validate device-reported response length before reading
Date: Wed, 19 Aug 2026 14:55:21 +0000 [thread overview]
Message-ID: <91f49a98dd42655829b7206f0d64cc31ef9c0e95@linux.dev> (raw)
From: Tianchu Chen <flynnnchen@tencent.com>
st95hf_spi_recv_response() reads a 2-byte header from the device,
derives the total response length from it (up to 1025 bytes via the
long-frame encoding) and then blindly reads len - 2 more bytes into
the caller's buffer, whose size it knows nothing about.
Call sites can be overflowed by a device reporting a large length,
for example, st95hf_irq_thread_handler() passes the data area of a
280-byte skb.
ST95HF datasheet states "In Reader mode it is possible to receive up to
528 bytes of frame data from VICC and TypeB cards", so technically a bogus
NFC tag may trigger the OOB-write if the card-reader's firmware allows
large packets.
Add a buff_len parameter and reject a device-reported length that does
not fit into the caller's buffer before issuing the second SPI
transfer. Also modify callers to pass their real buffer sizes.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
Fixes: cab47333f0f75 ("NFC: Add STMicroelectronics ST95HF driver")
Cc: stable@vger.kernel.org
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
---
drivers/nfc/st95hf/core.c | 6 ++++--
drivers/nfc/st95hf/spi.c | 7 ++++++-
drivers/nfc/st95hf/spi.h | 2 +-
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/nfc/st95hf/core.c b/drivers/nfc/st95hf/core.c
index 4d772a308bfff..0fbb60deada23 100644
--- a/drivers/nfc/st95hf/core.c
+++ b/drivers/nfc/st95hf/core.c
@@ -283,7 +283,8 @@ static int st95hf_send_recv_cmd(struct st95hf_context *st95context,
unsigned char st95hf_response_arr[2];
ret = st95hf_spi_recv_response(&st95context->spicontext,
- st95hf_response_arr);
+ st95hf_response_arr,
+ sizeof(st95hf_response_arr));
if (ret < 0) {
dev_err(dev, "spi error from st95hf_spi_recv_response(), err = 0x%x\n",
ret);
@@ -800,7 +801,8 @@ static irqreturn_t st95hf_irq_thread_handler(int irq, void *st95hfcontext)
mutex_lock(&stcontext->rm_lock);
res_len = st95hf_spi_recv_response(&stcontext->spicontext,
- skb_resp->data);
+ skb_resp->data,
+ skb_tailroom(skb_resp));
if (res_len < 0) {
dev_err(spidevice, "TISR spi response err = 0x%x\n", res_len);
result = res_len;
diff --git a/drivers/nfc/st95hf/spi.c b/drivers/nfc/st95hf/spi.c
index ffaf2789c4069..f48abd09a08fc 100644
--- a/drivers/nfc/st95hf/spi.c
+++ b/drivers/nfc/st95hf/spi.c
@@ -66,7 +66,7 @@ EXPORT_SYMBOL_GPL(st95hf_spi_send);
/* Function to Receive command Response */
int st95hf_spi_recv_response(struct st95hf_spi_context *spicontext,
- unsigned char *receivebuff)
+ unsigned char *receivebuff, int buff_len)
{
int len = 0;
struct spi_transfer tx_takedata;
@@ -106,6 +106,11 @@ int st95hf_spi_recv_response(struct st95hf_spi_context *spicontext,
else
len += receivebuff[1];
+ if (len > buff_len) {
+ mutex_unlock(&spicontext->spi_lock);
+ return -E2BIG;
+ }
+
/* Now make a transfer to read only relevant bytes */
tx_takedata.rx_buf = &receivebuff[2];
tx_takedata.len = len - 2;
diff --git a/drivers/nfc/st95hf/spi.h b/drivers/nfc/st95hf/spi.h
index 3ab678734c174..443a5053c0128 100644
--- a/drivers/nfc/st95hf/spi.h
+++ b/drivers/nfc/st95hf/spi.h
@@ -45,7 +45,7 @@ int st95hf_spi_send(struct st95hf_spi_context *spicontext,
enum req_type reqtype);
int st95hf_spi_recv_response(struct st95hf_spi_context *spicontext,
- unsigned char *receivebuff);
+ unsigned char *receivebuff, int buff_len);
int st95hf_spi_recv_echo_res(struct st95hf_spi_context *spicontext,
unsigned char *receivebuff);
--
2.51.0
reply other threads:[~2026-08-19 14:55 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=91f49a98dd42655829b7206f0d64cc31ef9c0e95@linux.dev \
--to=tianchu.chen@linux.dev \
--cc=david@ixit.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=oe-linux-nfc@lists.linux.dev \
--cc=sameo@linux.intel.com \
--cc=shikha.singh@st.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.