From: sashiko-bot@kernel.org
To: "Jonas Rebmann" <jre@pengutronix.de>
Cc: linux-sunxi@lists.linux.dev
Subject: Re: [PATCH 4/5] spi: spi-sun4i: sun4i_spi_handler(): fix race condition between transfer completion and RX FIFO interrupt
Date: Wed, 02 Sep 2026 15:47:44 +0000 [thread overview]
Message-ID: <20260902154744.748AB1F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260902-spi-sun4i-fixes-v1-4-19985ef75673@pengutronix.de>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] Data race and out-of-bounds write due to unsafe concurrent execution of `sun4i_spi_drain_fifo()` on the timeout path.
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but missing IRQ synchronization on the timeout error path leads to use-after-free and state corruption.
--
commit 2cab2ade096996934bf270db7137df45f943bc9b
Author: Marc Kleine-Budde <mkl@pengutronix.de>
spi: spi-sun4i: sun4i_spi_handler(): fix race condition between transfer completion and RX FIFO interrupt
This commit moves the RX-FIFO draining back to sun4i_spi_transfer_one() and
attempts to close a race window by disabling interrupts early in the IRQ
handler.
> diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
> index ae009d5984505..18951c1972da6 100644
> --- a/drivers/spi/spi-sun4i.c
> +++ b/drivers/spi/spi-sun4i.c
> @@ -333,6 +333,9 @@ static int sun4i_spi_transfer_one(struct spi_controller *host,
> start = jiffies;
> time_left = wait_for_completion_timeout(&sspi->done,
> msecs_to_jiffies(tx_time));
> +
> + sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> +
[Severity: High]
Can this unconditionally drain the FIFO while interrupts are still enabled?
If wait_for_completion_timeout() times out, the main thread will call
sun4i_spi_drain_fifo(). Because SPI interrupts are not disabled until the
subsequent timeout error block, a SUN4I_INT_CTL_RF_F34 interrupt can
fire concurrently.
This allows sun4i_spi_handler() to also invoke sun4i_spi_drain_fifo()
simultaneously:
CPU1:
sun4i_spi_transfer_one()
sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
if (sspi->rx_buf)
*sspi->rx_buf++ = byte;
CPU2:
sun4i_spi_handler()
if (status & SUN4I_INT_CTL_RF_F34) {
sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
if (sspi->rx_buf)
*sspi->rx_buf++ = byte;
Could this concurrent execution lead to non-atomic increments of sspi->rx_buf,
pointer corruption, and potential out-of-bounds memory writes?
> end = jiffies;
> if (!time_left) {
> dev_warn(&host->dev,
> @@ -340,13 +343,12 @@ static int sun4i_spi_transfer_one(struct spi_controller *host,
> dev_name(&spi->dev), tfr->len, tfr->speed_hz,
> jiffies_to_msecs(end - start), tx_time);
> ret = -ETIMEDOUT;
> + sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
> goto out;
> }
>
>
> out:
> - sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
> -
> return ret;
> }
[Severity: High]
This isn't a bug introduced by this patch, but does the timeout error path
need synchronization with currently executing IRQ handlers?
If an SPI transfer times out while the IRQ handler is already executing on
another CPU, the transfer function will disable interrupts at the controller
level, return -ETIMEDOUT, and the SPI core will tear down the transfer.
Since the code does not wait for in-flight handlers using synchronize_irq()
or a lock, the still-running sun4i_spi_handler() can subsequently write to
freed buffers in sun4i_spi_drain_fifo(), or call complete(&sspi->done)
which corrupts the state of the next transfer.
[ ... ]
> @@ -357,8 +359,7 @@ static irqreturn_t sun4i_spi_handler(int irq, void *dev_id)
>
> /* Transfer complete */
> if (status & SUN4I_INT_CTL_TC) {
> - sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC);
> - sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> + sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
> complete(&sspi->done);
> return IRQ_HANDLED;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260902-spi-sun4i-fixes-v1-0-19985ef75673@pengutronix.de?part=4
next prev parent reply other threads:[~2026-09-02 15:47 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 15:35 [PATCH 0/5] spi: spi-sun4i: assorted fixes Jonas Rebmann
2026-09-02 15:35 ` [PATCH 1/5] spi: spi-sun4i: sun4i_spi_transfer_one(): fix transfers for SUN4I_FIFO_DEPTH Jonas Rebmann
2026-09-02 15:49 ` sashiko-bot
2026-09-02 15:35 ` [PATCH 2/5] spi: spi-sun4i: sun4i_spi_fill_fifo(): always apply A10 FIFO fill level workaround Jonas Rebmann
2026-09-02 15:49 ` sashiko-bot
2026-09-02 15:35 ` [PATCH 3/5] spi: spi-sun4i: sun4i_spi_transfer_one(): fix setting of clock rate Jonas Rebmann
2026-09-02 15:47 ` sashiko-bot
2026-09-02 15:35 ` [PATCH 4/5] spi: spi-sun4i: sun4i_spi_handler(): fix race condition between transfer completion and RX FIFO interrupt Jonas Rebmann
2026-09-02 15:47 ` sashiko-bot [this message]
2026-09-02 15:35 ` [PATCH 5/5] spi: spi-sun4i: sun4i_spi_transfer_one(): report effectively used speed_hz of transfer Jonas Rebmann
2026-09-02 15:43 ` sashiko-bot
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=20260902154744.748AB1F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=jre@pengutronix.de \
--cc=linux-sunxi@lists.linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
/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.