From: sashiko-bot@kernel.org
To: "Benoît Monin" <benoit.monin@bootlin.com>
Cc: vkoul@kernel.org, dmaengine@vger.kernel.org, Frank.Li@kernel.org,
imx@lists.linux.dev
Subject: Re: [PATCH v11 1/2] dmaengine: fsl-edma: Implement device_prep_peripheral_dma_vec
Date: Wed, 16 Sep 2026 08:36:02 +0000 [thread overview]
Message-ID: <20260916083602.D05C31F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260916-fsl-edma-dyn-sg-v11-1-02792de71b92@bootlin.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] dmaengine: fsl-edma: division by zero in unaligned DMA_DEV_TO_DEV transfers
- [High] dmaengine: fsl-edma: loop mutates shared nbytes causing spurious transfer failures
- [High] dmaengine: fsl-edma: missing nb == 0 guard causes out-of-bounds heap read
--
commit 1a23f772b7926fbde5dc0fc2476442d47898d799
Author: Benoît Monin <benoit.monin@bootlin.com>
dmaengine: fsl-edma: Implement device_prep_peripheral_dma_vec
This commit adds the implementation of the .device_prep_peripheral_dma_vec()
callback to setup a scatter/gather DMA transfer from an array of dma_vec
structures. It also sets up a cyclic transfer if the DMA_PREP_REPEAT flag
is set.
> diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
> index bb7531c456dfa..8ba72b3d0e1af 100644
> --- a/drivers/dma/fsl-edma-common.c
> +++ b/drivers/dma/fsl-edma-common.c
[ ... ]
> @@ -673,6 +674,122 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
[ ... ]
> +struct dma_async_tx_descriptor *
> +fsl_edma_prep_peripheral_dma_vec(struct dma_chan *chan, const struct dma_vec *vecs,
> + size_t nb, enum dma_transfer_direction direction,
> + unsigned long flags)
> +{
> + struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> + dma_addr_t src_addr, dst_addr, last_sg;
> + struct fsl_edma_desc *fsl_desc;
> + u16 soff, doff, iter;
> + u32 nbytes;
> + int i;
> +
> + if (!is_slave_direction(direction))
> + return NULL;
> +
> + if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
> + return NULL;
> +
> + fsl_desc = fsl_edma_alloc_desc(fsl_chan, nb);
> + if (!fsl_desc)
> + return NULL;
[Severity: High]
Does this code allow an out-of-bounds heap read if `nb` is 0?
If `nb == 0` is passed, fsl_edma_alloc_desc() will allocate a descriptor with a
0-length flexible array of TCDs. The setup loop `for (i = 0; i < nb; i++)` is
skipped entirely, and the empty descriptor is directly submitted to the virtual
channel.
When the DMA engine tasklet processes this descriptor via
fsl_edma_xfer_desc(), it unconditionally executes fsl_chan->edesc->tcd[0].vtcd,
dereferencing an out-of-bounds heap address. Should there be a check for
`!nb` before allocating?
> + fsl_desc->iscyclic = flags & DMA_PREP_REPEAT;
> + fsl_desc->dirn = direction;
[ ... ]
> + for (i = 0; i < nb; i++) {
> + if (direction == DMA_MEM_TO_DEV) {
> + src_addr = vecs[i].addr;
> + dst_addr = fsl_chan->dma_dev_addr;
> + soff = fsl_chan->cfg.dst_addr_width;
> + doff = 0;
> + } else if (direction == DMA_DEV_TO_MEM) {
> + src_addr = fsl_chan->dma_dev_addr;
> + dst_addr = vecs[i].addr;
> + soff = 0;
> + doff = fsl_chan->cfg.src_addr_width;
> + } else {
> + /* DMA_DEV_TO_DEV */
> + src_addr = fsl_chan->cfg.src_addr;
> + dst_addr = fsl_chan->cfg.dst_addr;
> + soff = 0;
> + doff = 0;
> + }
> +
> + /*
> + * Choose the suitable burst length if dma_vec length is not
> + * multiple of burst length so that the whole transfer length is
> + * multiple of minor loop(burst length).
> + */
> + if (nbytes && vecs[i].len % nbytes) {
> + u32 width = (direction == DMA_DEV_TO_MEM) ? doff : soff;
[Severity: High]
Can this result in a modulo by zero kernel panic?
During DMA_DEV_TO_DEV configuration, both `soff` and `doff` are explicitly
initialized to 0. The calculation here results in `width = 0`. Then the
loop below evaluates `vecs[i].len % (j * width)`, which performs modulo by
zero.
> + u32 burst = (direction == DMA_DEV_TO_MEM) ?
> + fsl_chan->cfg.src_maxburst :
> + fsl_chan->cfg.dst_maxburst;
> + int j;
> +
> + for (j = burst; j > 1; j--) {
> + if (!(vecs[i].len % (j * width))) {
> + nbytes = j * width;
[Severity: High]
Does this loop mutate the shared `nbytes` variable causing spurious transfer
failures?
The `nbytes` variable is used to define the optimal burst length for the entire
transfer. Inside the loop, if an early vector is misaligned, the code
permanently shrinks `nbytes` (e.g., to 1 or a smaller factor) to fit that
specific vector without restoring it for the next loop iteration.
This degraded `nbytes` value leaks to all subsequent loop iterations. Large,
perfectly aligned vectors later in the array will incorrectly use the shrunken
`nbytes`.
> + break;
> + }
> + }
> + /* Set burst size as 1 if there's no suitable one */
> + if (j == 1)
> + nbytes = width;
> + }
> +
> + if (!nbytes || vecs[i].len / nbytes > FIELD_MAX(EDMA_TCD_ITER_MASK))
[Severity: High]
Does mutating `nbytes` above cause valid transfers to be rejected here?
As a result of permanently shrinking `nbytes` in a previous iteration,
`vecs[i].len / nbytes` can explode in magnitude and spuriously exceed
`FIELD_MAX(EDMA_TCD_ITER_MASK)` for perfectly valid DMA vectors.
> + goto err_free_desc;
> +
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260916-fsl-edma-dyn-sg-v11-0-02792de71b92@bootlin.com?part=1
next prev parent reply other threads:[~2026-09-16 8:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 8:24 [PATCH v11 0/2] dmaengine: fsl-edma: Scatter/gather improvements Benoît Monin
2026-09-16 8:24 ` [PATCH v11 1/2] dmaengine: fsl-edma: Implement device_prep_peripheral_dma_vec Benoît Monin
2026-09-16 8:36 ` sashiko-bot [this message]
2026-09-16 8:24 ` [PATCH v11 2/2] dmaengine: fsl-edma: Support dynamic scatter/gather chaining Benoît Monin
2026-10-02 12:00 ` [PATCH v11 0/2] dmaengine: fsl-edma: Scatter/gather improvements Benoît Monin
2026-10-05 15:43 ` Vinod Koul
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=20260916083602.D05C31F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=benoit.monin@bootlin.com \
--cc=dmaengine@vger.kernel.org \
--cc=imx@lists.linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@kernel.org \
/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