From: Weibin Liu <liuwb@xiaopeng.com>
To: broonie@kernel.org
Cc: pthombar@cadence.com, wsadowski@marvell.com,
linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: [PATCH 2/2] spi: cadence-xspi: fix stack buffer overflow in the Marvell b0 path
Date: Tue, 29 Sep 2026 16:11:45 +0800 [thread overview]
Message-ID: <20260929081146.41041-3-liuwb@xiaopeng.com> (raw)
In-Reply-To: <20260929081146.41041-1-liuwb@xiaopeng.com>
transfer_one_message_b0() falls back to a 10-byte stack buffer for
transfers which carry no TX data and points both in_buffer and
out_buffer into it.
With a transfer longer than 10 bytes the SDMA branch of the loop moves
up to MRVL_XFER_QWORD_COUNT * MRVL_XFER_QWORD_BYTECOUNT (256) bytes
through those pointers and then advances them by the same amount, so
both directions overflow the scratch buffer: a read transaction copies
SDMA data past the end of the buffer, a write transaction sends stack
contents from beyond it to the SPI bus.
Size the scratch buffer for the largest chunk the loop can request,
keep the buffer pointers pinned to it when the message does not carry
the corresponding TX or RX data, and only advance the pointers which
reference real transfer buffers. Also zero-initialize the scratch
buffer so that padding bytes sent for TX-less transfers no longer leak
uninitialized stack contents.
Fixes: 5cb7651f78e1 ("Marvell HW overlay support for Cadence xSPI")
Cc: stable@vger.kernel.org # 6.11+
Signed-off-by: Weibin Liu <liuwb@xiaopeng.com>
---
Reviewer notes:
- transfer_one_message_b0() only runs on controllers with the Marvell
overlay (marvell,cn10-xspi-nor); the loop chunks every transfer into
SDMA rounds of up to MRVL_XFER_QWORD_COUNT * MRVL_XFER_QWORD_BYTECOUNT
(256) bytes.
- The scratch buffer stays on the stack but is now sized for the largest
chunk a single SDMA round can move; the old u8 data[10] was too small
for any transfer longer than 10 bytes.
- The pointers are only advanced when they reference the real transfer
buffers, and the buffer is zero-initialized so that TX-less transfers
no longer clock out uninitialized stack bytes to the attached device.
Tested on x86_64: with this patch applied the driver builds, loads and
unloads cleanly; no controller with the Marvell overlay is available to
exercise the b0 path on hardware.
drivers/spi/spi-cadence-xspi.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index 1f1cd4535..3687853e4 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -268,6 +268,7 @@
#define MRVL_XFER_FUNC_START BIT(0)
#define MRVL_XFER_QWORD_COUNT 32
#define MRVL_XFER_QWORD_BYTECOUNT 8
+#define MRVL_XFER_MAX_LEN (MRVL_XFER_QWORD_COUNT * MRVL_XFER_QWORD_BYTECOUNT)
#define MRVL_XSPI_POLL_TIMEOUT_US 1000
#define MRVL_XSPI_POLL_DELAY_US 10
@@ -1107,7 +1108,7 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller,
struct spi_device *spi = m->spi;
struct spi_transfer *t = NULL;
- const unsigned int max_len = MRVL_XFER_QWORD_BYTECOUNT * MRVL_XFER_QWORD_COUNT;
+ const unsigned int max_len = MRVL_XFER_MAX_LEN;
int current_transfer_len;
int cs = spi_get_chipselect(spi, 0);
int cs_change = 0;
@@ -1130,13 +1131,16 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller,
list_for_each_entry(t, &m->transfers, transfer_list) {
u8 *txd = (u8 *) t->tx_buf;
u8 *rxd = (u8 *) t->rx_buf;
- u8 data[10];
+ u8 data[MRVL_XFER_MAX_LEN] = {0};
u32 cmd_regs[6];
if (!txd)
txd = data;
- cdns_xspi->in_buffer = txd + 1;
+ if (rxd)
+ cdns_xspi->in_buffer = rxd;
+ else
+ cdns_xspi->in_buffer = data;
cdns_xspi->out_buffer = txd + 1;
while (t->len) {
@@ -1163,8 +1167,10 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller,
if (!cdns_xspi_is_stig_ready(cdns_xspi, true))
return -EIO;
- cdns_xspi->in_buffer += current_transfer_len;
- cdns_xspi->out_buffer += current_transfer_len;
+ if (rxd)
+ cdns_xspi->in_buffer += current_transfer_len;
+ if (t->tx_buf)
+ cdns_xspi->out_buffer += current_transfer_len;
}
if (rxd) {
--
2.50.1
prev parent reply other threads:[~2026-09-29 8:11 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-29 8:11 [PATCH 0/2] spi: cadence-xspi: two memory-safety fixes in the slave-DMA paths Weibin Liu
2026-09-29 8:11 ` [PATCH 1/2] spi: cadence-xspi: reject SDMA transfers larger than the requested length Weibin Liu
2026-09-29 8:11 ` Weibin Liu [this message]
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=20260929081146.41041-3-liuwb@xiaopeng.com \
--to=liuwb@xiaopeng.com \
--cc=broonie@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-spi@vger.kernel.org \
--cc=pthombar@cadence.com \
--cc=stable@vger.kernel.org \
--cc=wsadowski@marvell.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
all inboxes | Powered by JetHome®