From: sashiko-bot@kernel.org
To: "Hongling Zeng" <zenghongling@kylinos.cn>
Cc: vkoul@kernel.org, linux-sunxi@lists.linux.dev,
Frank.Li@kernel.org, dmaengine@vger.kernel.org
Subject: Re: [PATCH RESEND v5] dmaengine: sun6i-dma: Fix use-after-free in error handling paths
Date: Mon, 27 Jul 2026 06:24:37 +0000 [thread overview]
Message-ID: <20260727062437.944BF1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260727061142.44195-1-zenghongling@kylinos.cn>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing input validation in `sun6i_dma_prep_dma_cyclic()` leads to a divide-by-zero panic or a NULL pointer dereference when setting up the cyclic list.
- [High] Failing to validate `sg_len > 0` in `sun6i_dma_prep_slave_sg()` allows submission of an empty descriptor, leading to a hardware fault.
- [High] A race condition in `sun6i_dma_tx_status()` leads to a Use-After-Free when querying the status of a transfer.
--
--- Patch [1]: [PATCH RESEND v5] dmaengine: sun6i-dma: Fix use-after-free in error handling paths ---
commit f42009e17697997cd6fc8eda0aef5712caa48d76
Author: Hongling Zeng <zenghongling@kylinos.cn>
Subject: dmaengine: sun6i-dma: Fix use-after-free in error handling paths
This commit fixes a use-after-free in the error handling paths of the
sun6i-dma driver by refactoring the descriptor cleanup into a new helper
function. It also introduces a virtual descriptor freeing helper for vchan.
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index a9a254dbf8cb9..7a79f346250a5 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
[ ... ]
> @@ -788,10 +795,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
> return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
>
> err_lli_free:
[Severity: High]
This isn't a bug introduced by this patch, but does the validation in
sun6i_dma_prep_slave_sg() need to check for empty scatterlists?
The function checks if the scatterlist pointer is valid:
if (!sgl)
return NULL;
However, if sg_len is 0, the for_each_sg() loop is bypassed entirely.
This leaves txd->p_lli as 0. When this descriptor is later executed by
sun6i_dma_start_desc(), the hardware LLI address register is programmed
with physical address 0:
writel(pchan->desc->p_lli, pchan->base + DMA_CHAN_LLI_ADDR);
Could this cause a hardware fault by instructing the DMA controller to
fetch its configuration from physical address 0?
> - for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
> - p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
> - dma_pool_free(sdev->pool, v_lli, p_lli);
> - kfree(txd);
> + sun6i_dma_free_desc(sdev, txd);
> return NULL;
> }
[ ... ]
> @@ -869,10 +873,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
> return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
>
> err_lli_free:
[Severity: High]
This is a pre-existing issue, but I noticed a potential divide-by-zero
and NULL pointer dereference in sun6i_dma_prep_dma_cyclic().
If a caller passes period_len as 0, does this calculation cause a
divide-by-zero exception?
unsigned int i, periods = buf_len / period_len;
Additionally, if buf_len is less than period_len, periods evaluates to 0.
This skips the allocation loop entirely, leaving the prev pointer
uninitialized (NULL). Would the subsequent attempt to make the list
cyclic cause a NULL pointer dereference?
prev->p_lli_next = txd->p_lli;
> - for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
> - p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
> - dma_pool_free(sdev->pool, v_lli, p_lli);
> - kfree(txd);
> + sun6i_dma_free_desc(sdev, txd);
> return NULL;
> }
[ ... ]
[Severity: High]
This is a pre-existing issue, but I noticed a potential race condition
when querying the status of a transfer.
In sun6i_dma_tx_status(), the function queries dma_cookie_status()
outside the channel lock:
ret = dma_cookie_status(chan, cookie, state);
If the cookie status is DMA_IN_PROGRESS, can the thread be preempted
before taking the lock?
During this window, the hardware interrupt could fire, completing the
transfer and triggering the vchan_complete tasklet which frees the
descriptor memory.
When sun6i_dma_tx_status() resumes and acquires the lock, it might fail
to find the descriptor in the pending lists and fall back to calculating
the size using the active physical channel state:
bytes = sun6i_get_chan_size(pchan);
Inside sun6i_get_chan_size(), this would dereference the freed descriptor:
pos = pchan->desc->p_lli;
Since pchan->desc is cleared by sun6i_dma_tasklet running sequentially
afterwards, could this lead to a use-after-free?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727061142.44195-1-zenghongling@kylinos.cn?part=1
prev parent reply other threads:[~2026-07-27 6:24 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-27 6:11 [PATCH RESEND v5] dmaengine: sun6i-dma: Fix use-after-free in error handling paths Hongling Zeng
2026-07-27 6:24 ` sashiko-bot [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=20260727062437.944BF1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@kernel.org \
--cc=zenghongling@kylinos.cn \
/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.