Re: [PATCH] dmaengine: sun6i: fix use-after-free in descriptor error path

Frank Li <[email protected]>
Newsgroups org.kernel.vger.dmaengine,dev.linux.lists.linux-sunxi,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <an-B5SdpGfsJoudH@lizhi-Precision-Tower-5810>
On Fri, Aug 14, 2026 at 03:06:30PM -0400, Frank Li wrote:
> On Mon, Aug 10, 2026 at 10:20:44AM +0000, Chaithanya Lagisetty wrote:
> > The err_lli_free cleanup loops in sun6i_dma_prep_slave_sg() and
> > sun6i_dma_prep_dma_cyclic() free each LLI node with dma_pool_free()
> > and then dereference the freed node to obtain v_lli_next and
> > p_lli_next for the next loop iteration.
> >
> > Save the next pointers before freeing, matching the pattern already used
> > in sun6i_dma_free_desc().
> >
> > Fixes: 9aa48806edb8 ("dmaengine: sun6i: Do not use virt_to_phys")
> > Signed-off-by: Chaithanya Lagisetty <[email protected]>
> > ---
>
> Reviewed-by: Frank Li <[email protected]>

Drop review-by, I prefer use below method to fix

https://patchwork.kernel.org/project/linux-dmaengine/patch/[email protected]/

Frank
>
> >  drivers/dma/sun6i-dma.c | 18 ++++++++++++------
> >  1 file changed, 12 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index f47a326dd7ff..2439fa6564f2 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -720,10 +720,10 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
> >  	struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device);
> >  	struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
> >  	struct dma_slave_config *sconfig = &vchan->cfg;
> > -	struct sun6i_dma_lli *v_lli, *prev = NULL;
> > +	struct sun6i_dma_lli *v_lli, *v_next, *prev = NULL;
> >  	struct sun6i_desc *txd;
> >  	struct scatterlist *sg;
> > -	dma_addr_t p_lli;
> > +	dma_addr_t p_lli, p_next;
> >  	u32 lli_cfg;
> >  	int i, ret;
> >
> > @@ -789,8 +789,11 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
> >
> >  err_lli_free:
> >  	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)
> > +	     p_lli = p_next, v_lli = v_next) {
> > +		v_next = v_lli->v_lli_next;
> > +		p_next = v_lli->p_lli_next;
> >  		dma_pool_free(sdev->pool, v_lli, p_lli);
> > +	}
> >  	kfree(txd);
> >  	return NULL;
> >  }
> > @@ -806,9 +809,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
> >  	struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device);
> >  	struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
> >  	struct dma_slave_config *sconfig = &vchan->cfg;
> > -	struct sun6i_dma_lli *v_lli, *prev = NULL;
> > +	struct sun6i_dma_lli *v_lli, *v_next, *prev = NULL;
> >  	struct sun6i_desc *txd;
> > -	dma_addr_t p_lli;
> > +	dma_addr_t p_lli, p_next;
> >  	u32 lli_cfg;
> >  	unsigned int i, periods = buf_len / period_len;
> >  	int ret;
> > @@ -870,8 +873,11 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
> >
> >  err_lli_free:
> >  	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)
> > +	     p_lli = p_next, v_lli = v_next) {
> > +		v_next = v_lli->v_lli_next;
> > +		p_next = v_lli->p_lli_next;
> >  		dma_pool_free(sdev->pool, v_lli, p_lli);
> > +	}
> >  	kfree(txd);
> >  	return NULL;
> >  }
> > --
> > 2.43.0
> >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.