Re: [PATCH v2 58/64] dmaengine: qcom-adm: use dma_chan_kill_bh
[email protected] Mon, 27 Jul 2026 21:17:20 +0000
| Newsgroups | org.kernel.vger.dmaengine |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: Pre-existing issues: - [High] Teardown race condition in adm_dma_remove() leading to use-after-free - [High] Missing device_synchronize callback exposes DMA clients to use-after-free -- --- Patch [58]: [PATCH v2 58/64] dmaengine: qcom-adm: use dma_chan_kill_bh --- commit be25e9ce5563c30843636df639280bce697e48d5 Author: Allen Pais <[email protected]> dmaengine: qcom-adm: use dma_chan_kill_bh virt-dma now dispatches completion callbacks through per-channel BH work instead of its tasklet. Cancel that work during teardown before channel storage is released. > diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c > index 07fbe32d31fa4..ea24e2de51544 100644 > --- a/drivers/dma/qcom/qcom_adm.c > +++ b/drivers/dma/qcom/qcom_adm.c > @@ -918,8 +918,8 @@ static void adm_dma_remove(struct platform_device *pdev) > /* mask IRQs for this channel/EE pair */ > writel(0, adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee)); > > - tasklet_kill(&adev->channels[i].vc.task); > - adm_terminate_all(&adev->channels[i].vc.chan); > + dma_chan_kill_bh(&achan->vc.chan); [Severity: High] This is a pre-existing issue, but does this sequence leave a window for a use-after-free? If adm_dma_remove() calls dma_chan_kill_bh() before devm_free_irq() synchronizes with the interrupt handler, a concurrent interrupt can still fire: cpu1 adm_dma_remove() writel(0, ...) dma_chan_kill_bh() cpu2 adm_dma_irq() vchan_cookie_complete() dma_chan_schedule_bh() Because cpu1 proceeds to devm_free_irq() which waits for the interrupt handler to finish but does not flush the newly queued bottom-half work, the device context is subsequently freed. The workqueue could then execute the scheduled bottom-half work on the freed memory. Could devm_free_irq() be explicitly called before tearing down the channels? [Severity: High] This isn't a bug introduced by this patch, but does this driver also lack a device_synchronize callback during its initialization in adm_dma_probe()? When clients call dmaengine_terminate_sync() to abort transactions, it relies on device_synchronize (usually mapped to vchan_synchronize) to wait for callbacks to complete. Without it, dmaengine_terminate_sync() returns immediately, and clients may free their buffers while the virt-dma bottom-half work is still executing. Can this lead to a use-after-free in the client's completion callback? > + adm_terminate_all(&achan->vc.chan); > } > > devm_free_irq(adev->dev, adev->irq, adev); -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=58