All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Hongling Zeng" <zenghongling@kylinos.cn>
Cc: linux-sunxi@lists.linux.dev, vkoul@kernel.org,
	Frank.Li@kernel.org, dmaengine@vger.kernel.org
Subject: Re: [PATCH v4] dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all
Date: Thu, 18 Jun 2026 02:16:43 +0000	[thread overview]
Message-ID: <20260618021644.506581F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260618020609.1155962-1-zenghongling@kylinos.cn>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Lockless read of `vchan->phy` causes a Time-of-Check to Time-of-Use (TOCTOU) race, leading to cross-channel list corruption and improper hardware state modifications.
- [High] Lack of synchronization between `sun6i_dma_terminate_all` and the hardirq handler `sun6i_dma_interrupt` leads to an unmitigated NULL pointer dereference.
--

commit 0f302155373f5ca26acb89959d317a9f6c68ecc0
Author: Hongling Zeng <zenghongling@kylinos.cn>

dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all

This commit fixes a memory leak when terminating DMA transfers by using
vchan_terminate_vdesc() to handle both cyclic and non-cyclic descriptors.
It also prevents completed descriptors from being double-added to the list.

> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index a9a254dbf8cb9..f47a326dd7ffa 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -945,16 +945,13 @@ static int sun6i_dma_terminate_all(struct dma_chan *chan)
>  
>  	spin_lock_irqsave(&vchan->vc.lock, flags);
>  
> -	if (vchan->cyclic) {
> -		vchan->cyclic = false;
> -		if (pchan && pchan->desc) {
> -			struct virt_dma_desc *vd = &pchan->desc->vd;
> -			struct virt_dma_chan *vc = &vchan->vc;
> +	if (pchan && pchan->desc && pchan->desc != pchan->done) {
> +		struct virt_dma_desc *vd = &pchan->desc->vd;
>  
> -			list_add_tail(&vd->node, &vc->desc_completed);
> -		}
> +		vchan_terminate_vdesc(vd);

[Severity: High]
This is a pre-existing issue, but by calling vchan_terminate_vdesc() here,
does this code now trigger list corruption or a lockdep splat?

Earlier in sun6i_dma_terminate_all(), the physical channel is read locklessly:

    struct sun6i_pchan *pchan = vchan->phy;

If a concurrent DMA tasklet frees and reassigns this physical channel to a
completely different virtual channel before spin_lock_irqsave() is acquired,
we evaluate a stale pchan. Passing this foreign descriptor into
vchan_terminate_vdesc() will attempt to add it to desc_terminated while
holding the wrong lock, corrupting the list.

>  	}
>  
> +	vchan->cyclic = false;
>  	vchan_get_all_descriptors(&vchan->vc, &head);
>  
>  	if (pchan) {

[Severity: High]
This is a pre-existing issue, but does clearing the physical channel state
here lead to a NULL pointer dereference in the interrupt handler?

Just below this hunk in sun6i_dma_terminate_all(), the code sets
pchan->desc = NULL without synchronizing with the IRQ handler:

    if (pchan) {
        writel(DMA_CHAN_ENABLE_STOP, pchan->base + DMA_CHAN_ENABLE);
        writel(DMA_CHAN_PAUSE_RESUME, pchan->base + DMA_CHAN_PAUSE);
        vchan->phy = NULL;
        pchan->vchan = NULL;
        pchan->desc = NULL;
        pchan->done = NULL;
    }

If sun6i_dma_interrupt() is running concurrently on another CPU, it
could be executing vchan_cookie_complete(&pchan->desc->vd) or
vchan_cyclic_callback(&pchan->desc->vd). Without synchronize_irq()
or similar to wait for pending handlers, this will pass a NULL offset
to those helpers, which then dereference vd->tx.chan.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260618020609.1155962-1-zenghongling@kylinos.cn?part=1

  reply	other threads:[~2026-06-18  2:16 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-18  2:06 [PATCH v4] dmaengine: sun6i-dma: Fix memory leak in sun6i_dma_terminate_all Hongling Zeng
2026-06-18  2:16 ` sashiko-bot [this message]
2026-06-18  3:22 ` Frank Li

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=20260618021644.506581F000E9@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.