Re: [PATCH v3 01/11] dmaengine: switchtec-dma: fix double-free in switchtec_dma_free_desc()
From: Frank Li
Date: Mon Jul 27 2026 - 16:56:48 EST
On Mon, Jul 27, 2026 at 12:15:16PM -0600, Logan Gunthorpe wrote:
> switchtec_dma_free_desc() frees swdma_chan->hw_sq, hw_cq, and every
> desc_ring[] entry without clearing the pointers afterward. If
> switchtec_dma_alloc_chan_resources() fails partway through and calls
> it during unwind, then a later retry of alloc_chan_resources() fails
> in switchtec_dma_alloc_desc() before reallocating one of those
> pointers, its own failure path calls switchtec_dma_free_desc() again
> and frees the same, already-freed pointers a second time.
>
> NULL out each pointer as it's freed so a subsequent call is a no-op
> for anything already released.
>
> Fixes: 30eba9df76ad ("dmaengine: switchtec-dma: Implement hardware initialization and cleanup")
> Signed-off-by: Logan Gunthorpe <logang@xxxxxxxxxxxx>
> ---
Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
> drivers/dma/switchtec_dma.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c
> index 3ef928640615..a4a7d66d042d 100644
> --- a/drivers/dma/switchtec_dma.c
> +++ b/drivers/dma/switchtec_dma.c
> @@ -886,14 +886,18 @@ static void switchtec_dma_free_desc(struct switchtec_dma_chan *swdma_chan)
> if (swdma_chan->hw_sq)
> dma_free_coherent(swdma_dev->dma_dev.dev, size,
> swdma_chan->hw_sq, swdma_chan->dma_addr_sq);
> + swdma_chan->hw_sq = NULL;
>
> size = SWITCHTEC_DMA_CQ_SIZE * sizeof(*swdma_chan->hw_cq);
> if (swdma_chan->hw_cq)
> dma_free_coherent(swdma_dev->dma_dev.dev, size,
> swdma_chan->hw_cq, swdma_chan->dma_addr_cq);
> + swdma_chan->hw_cq = NULL;
>
> - for (i = 0; i < SWITCHTEC_DMA_RING_SIZE; i++)
> + for (i = 0; i < SWITCHTEC_DMA_RING_SIZE; i++) {
> kfree(swdma_chan->desc_ring[i]);
> + swdma_chan->desc_ring[i] = NULL;
> + }
> }
>
> static int switchtec_dma_alloc_desc(struct switchtec_dma_chan *swdma_chan)
> --
> 2.47.3
>