[PATCH] spi: sprd-adi: reject transfers shorter than 4 bytes

From: Weibin Liu

Date: Wed Oct 14 2026 - 10:08:07 EST


sprd_adi_transfer_one() dereferences t->rx_buf and t->tx_buf as u32
without validating t->len. The SPI core does not enforce a 4-byte
minimum, so a transfer of 1..3 bytes (e.g. via spidev) makes the
driver read 4 bytes through (u32 *)t->rx_buf and store the result
back, and on the write path read two consecutive u32 values from
t->tx_buf. With a buffer allocated for fewer bytes this runs off the
end of it: the read path reads and writes up to 3 bytes past the
allocation and the write path reads up to 7 bytes past it, corrupting
adjacent heap objects.

The ADI protocol only supports 4-byte register accesses, so reject any
transfer shorter than 4 bytes with -EINVAL before touching the buffers.

Reproduced with a user-space replica (ASAN build): a 4-byte u32 access
from a 3-byte buffer triggers a stack-buffer-overflow READ of size 4.
No Spreadtrum hardware was available, so the -EINVAL rejection itself
was verified by inspection.

Reviewed-by: Liu Chao <liuc63@xxxxxxxxxxxx>
Fixes: 7e2903cb91df ("spi: Add ADI driver for Spreadtrum platform")
Cc: stable@xxxxxxxxxxxxxxx # 4.15+
Signed-off-by: Weibin Liu <liuwb@xxxxxxxxxxxx>
---
drivers/spi/spi-sprd-adi.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index a6baaf02b3c8..24ece07ab5e6 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -338,6 +338,12 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
u32 reg, val;
int ret;

+ /* ADI only supports 4-byte register accesses */
+ if (t->len < 4) {
+ dev_err(sadi->dev, "invalid transfer length %u\n", t->len);
+ return -EINVAL;
+ }
+
if (t->rx_buf) {
reg = *(u32 *)t->rx_buf;
ret = sprd_adi_read(sadi, reg, &val);

---
base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
change-id: 20261014-spi-sprd-adi-minlen-28560f9ed795

Best regards,
--
Weibin Liu <liuwb@xxxxxxxxxxxx>