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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox