mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Weibin Liu <liuwb@xiaopeng.com>
To: Baolin Wang <baolin.wang@linux.alibaba.com>,
	Orson Zhai <orsonzhai@gmail.com>, Mark Brown <broonie@kernel.org>,
	Lee Jones <lee@kernel.org>
Cc: Weibin Liu <liuwb@xiaopeng.com>,
	linux-kernel@vger.kernel.org, stable@vger.kernel.org,
	linux-spi@vger.kernel.org, Chunyan Zhang <zhang.lyra@gmail.com>,
	mfd@lists.linux.dev, Guanglei Zhu <zhugl3@xiaopeng.com>,
	Sashiko <sashiko-bot@kernel.org>
Subject: [PATCH v3 2/2] spi: sprd-adi: enforce the exact transfer length
Date: Mon, 26 Oct 2026 23:32:53 +0800	[thread overview]
Message-ID: <20261026153253.689525-3-liuwb@xiaopeng.com> (raw)
In-Reply-To: <20261026153253.689525-1-liuwb@xiaopeng.com>

sprd_adi_transfer_one() never looks at the transfer length: the
read path dereferences t->rx_buf as one u32 and stores the result
back, and the write path reads two consecutive u32 values from
t->tx_buf. A transfer whose length does not exactly match what the
controller touches is a bug in the caller: a short transfer reads
or writes past the end of the buffer, and a long transfer is
silently truncated.

The SPI core does not enforce the expected length, so reject reads
whose length is not exactly sizeof(u32) and writes whose length is
not exactly 2 * sizeof(u32) with -EINVAL before touching the
buffers. If the controller is exposed through spidev, a userspace
client can submit invalid transfers in a tight loop, so use
dev_err_ratelimited() for the driver's rejection messages.

The only in-tree user, the SC27xx PMIC driver, is updated by the
previous patch to advertise the byte length of an ADI register
access.

Tested in QEMU (aarch64 virt) against Linux 7.3-rc7, with the
controller node added to the guest device tree. QEMU has no model
of this hardware (the MMIO window is backed by RAM), so this only
exercises the software path. Transfers submitted through spidev
confirm the new checks: a 4-byte read and an 8-byte write are
accepted, every other length from 1 to 16 is rejected with
-EINVAL. A burst of 32 invalid reads and 32 invalid writes emits
only 10 messages at each new driver call site. The SC27xx driver's
transfers pass once it advertises the byte length. No Spreadtrum
hardware was available.

Fixes: 7e2903cb91df ("spi: Add ADI driver for Spreadtrum platform")
Cc: stable@vger.kernel.org # 4.15+
Signed-off-by: Weibin Liu <liuwb@xiaopeng.com>
Reviewed-by: Guanglei Zhu <zhugl3@xiaopeng.com>
---
Changes in v3:
- Rate-limit invalid-length errors as suggested by Sashiko's review.

 drivers/spi/spi-sprd-adi.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index a6baaf02b3c8..32e445cea0d3 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -339,10 +339,24 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
 	int ret;
 
 	if (t->rx_buf) {
+		/* ADI reads consume exactly one u32: reg in, value out. */
+		if (t->len != sizeof(u32)) {
+			dev_err_ratelimited(sadi->dev,
+					    "invalid read length %u\n",
+					    t->len);
+			return -EINVAL;
+		}
 		reg = *(u32 *)t->rx_buf;
 		ret = sprd_adi_read(sadi, reg, &val);
 		*(u32 *)t->rx_buf = val;
 	} else if (t->tx_buf) {
+		/* ADI writes consume exactly two u32: reg and value. */
+		if (t->len != 2 * sizeof(u32)) {
+			dev_err_ratelimited(sadi->dev,
+					    "invalid write length %u\n",
+					    t->len);
+			return -EINVAL;
+		}
 		u32 *p = (u32 *)t->tx_buf;
 		reg = *p++;
 		val = *p;
-- 
2.50.1


      parent reply	other threads:[~2026-10-26 15:33 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26 15:32 [PATCH v3 0/2] mfd/spi: sprd: fix ADI transfer length handling Weibin Liu
2026-10-26 15:32 ` [PATCH v3 1/2] mfd: sprd-sc27xx: Pass byte length to spi_read() Weibin Liu
2026-10-26 15:32 ` 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=20261026153253.689525-3-liuwb@xiaopeng.com \
    --to=liuwb@xiaopeng.com \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=broonie@kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=mfd@lists.linux.dev \
    --cc=orsonzhai@gmail.com \
    --cc=sashiko-bot@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=zhang.lyra@gmail.com \
    --cc=zhugl3@xiaopeng.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®