* [PATCH] dmaengine: tegra-adma: Fix use-after-free
@ 2025-11-10 14:24 Sheetal .
2025-11-27 9:25 ` Thierry Reding
2025-12-16 16:56 ` Vinod Koul
0 siblings, 2 replies; 4+ messages in thread
From: Sheetal . @ 2025-11-10 14:24 UTC (permalink / raw)
To: vkoul
Cc: ldewangan, jonathanh, thierry.reding, dmaengine, linux-tegra,
linux-kernel, Sheetal
From: Sheetal <sheetal@nvidia.com>
A use-after-free bug exists in the Tegra ADMA driver when audio streams
are terminated, particularly during XRUN conditions. The issue occurs
when the DMA buffer is freed by tegra_adma_terminate_all() before the
vchan completion tasklet finishes accessing it.
The race condition follows this sequence:
1. DMA transfer completes, triggering an interrupt that schedules the
completion tasklet (tasklet has not executed yet)
2. Audio playback stops, calling tegra_adma_terminate_all() which
frees the DMA buffer memory via kfree()
3. The scheduled tasklet finally executes, calling vchan_complete()
which attempts to access the already-freed memory
Since tasklets can execute at any time after being scheduled, there is
no guarantee that the buffer will remain valid when vchan_complete()
runs.
Fix this by properly synchronizing the virtual channel completion:
- Calling vchan_terminate_vdesc() in tegra_adma_stop() to mark the
descriptors as terminated instead of freeing the descriptor.
- Add the callback tegra_adma_synchronize() that calls
vchan_synchronize() which kills any pending tasklets and frees any
terminated descriptors.
Crash logs:
[ 337.427523] BUG: KASAN: use-after-free in vchan_complete+0x124/0x3b0
[ 337.427544] Read of size 8 at addr ffff000132055428 by task swapper/0/0
[ 337.427562] Call trace:
[ 337.427564] dump_backtrace+0x0/0x320
[ 337.427571] show_stack+0x20/0x30
[ 337.427575] dump_stack_lvl+0x68/0x84
[ 337.427584] print_address_description.constprop.0+0x74/0x2b8
[ 337.427590] kasan_report+0x1f4/0x210
[ 337.427598] __asan_load8+0xa0/0xd0
[ 337.427603] vchan_complete+0x124/0x3b0
[ 337.427609] tasklet_action_common.constprop.0+0x190/0x1d0
[ 337.427617] tasklet_action+0x30/0x40
[ 337.427623] __do_softirq+0x1a0/0x5c4
[ 337.427628] irq_exit+0x110/0x140
[ 337.427633] handle_domain_irq+0xa4/0xe0
[ 337.427640] gic_handle_irq+0x64/0x160
[ 337.427644] call_on_irq_stack+0x20/0x4c
[ 337.427649] do_interrupt_handler+0x7c/0x90
[ 337.427654] el1_interrupt+0x30/0x80
[ 337.427659] el1h_64_irq_handler+0x18/0x30
[ 337.427663] el1h_64_irq+0x7c/0x80
[ 337.427667] cpuidle_enter_state+0xe4/0x540
[ 337.427674] cpuidle_enter+0x54/0x80
[ 337.427679] do_idle+0x2e0/0x380
[ 337.427685] cpu_startup_entry+0x2c/0x70
[ 337.427690] rest_init+0x114/0x130
[ 337.427695] arch_call_rest_init+0x18/0x24
[ 337.427702] start_kernel+0x380/0x3b4
[ 337.427706] __primary_switched+0xc0/0xc8
Fixes: f46b195799b5 ("dmaengine: tegra-adma: Add support for Tegra210 ADMA")
Signed-off-by: Sheetal <sheetal@nvidia.com>
---
drivers/dma/tegra210-adma.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
index fad896ff29a2..812f64569e6d 100644
--- a/drivers/dma/tegra210-adma.c
+++ b/drivers/dma/tegra210-adma.c
@@ -429,10 +429,17 @@ static void tegra_adma_stop(struct tegra_adma_chan *tdc)
return;
}
- kfree(tdc->desc);
+ vchan_terminate_vdesc(&tdc->desc->vd);
tdc->desc = NULL;
}
+static void tegra_adma_synchronize(struct dma_chan *dc)
+{
+ struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
+
+ vchan_synchronize(&tdc->vc);
+}
+
static void tegra_adma_start(struct tegra_adma_chan *tdc)
{
struct virt_dma_desc *vd = vchan_next_desc(&tdc->vc);
@@ -1155,6 +1162,7 @@ static int tegra_adma_probe(struct platform_device *pdev)
tdma->dma_dev.device_config = tegra_adma_slave_config;
tdma->dma_dev.device_tx_status = tegra_adma_tx_status;
tdma->dma_dev.device_terminate_all = tegra_adma_terminate_all;
+ tdma->dma_dev.device_synchronize = tegra_adma_synchronize;
tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] dmaengine: tegra-adma: Fix use-after-free
2025-11-10 14:24 [PATCH] dmaengine: tegra-adma: Fix use-after-free Sheetal .
@ 2025-11-27 9:25 ` Thierry Reding
2025-12-16 15:23 ` Vinod Koul
2025-12-16 16:56 ` Vinod Koul
1 sibling, 1 reply; 4+ messages in thread
From: Thierry Reding @ 2025-11-27 9:25 UTC (permalink / raw)
To: Sheetal .
Cc: vkoul, ldewangan, jonathanh, dmaengine, linux-tegra, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 3283 bytes --]
On Mon, Nov 10, 2025 at 07:54:45PM +0530, Sheetal . wrote:
> From: Sheetal <sheetal@nvidia.com>
>
> A use-after-free bug exists in the Tegra ADMA driver when audio streams
> are terminated, particularly during XRUN conditions. The issue occurs
> when the DMA buffer is freed by tegra_adma_terminate_all() before the
> vchan completion tasklet finishes accessing it.
>
> The race condition follows this sequence:
>
> 1. DMA transfer completes, triggering an interrupt that schedules the
> completion tasklet (tasklet has not executed yet)
> 2. Audio playback stops, calling tegra_adma_terminate_all() which
> frees the DMA buffer memory via kfree()
> 3. The scheduled tasklet finally executes, calling vchan_complete()
> which attempts to access the already-freed memory
>
> Since tasklets can execute at any time after being scheduled, there is
> no guarantee that the buffer will remain valid when vchan_complete()
> runs.
>
> Fix this by properly synchronizing the virtual channel completion:
> - Calling vchan_terminate_vdesc() in tegra_adma_stop() to mark the
> descriptors as terminated instead of freeing the descriptor.
> - Add the callback tegra_adma_synchronize() that calls
> vchan_synchronize() which kills any pending tasklets and frees any
> terminated descriptors.
>
> Crash logs:
> [ 337.427523] BUG: KASAN: use-after-free in vchan_complete+0x124/0x3b0
> [ 337.427544] Read of size 8 at addr ffff000132055428 by task swapper/0/0
>
> [ 337.427562] Call trace:
> [ 337.427564] dump_backtrace+0x0/0x320
> [ 337.427571] show_stack+0x20/0x30
> [ 337.427575] dump_stack_lvl+0x68/0x84
> [ 337.427584] print_address_description.constprop.0+0x74/0x2b8
> [ 337.427590] kasan_report+0x1f4/0x210
> [ 337.427598] __asan_load8+0xa0/0xd0
> [ 337.427603] vchan_complete+0x124/0x3b0
> [ 337.427609] tasklet_action_common.constprop.0+0x190/0x1d0
> [ 337.427617] tasklet_action+0x30/0x40
> [ 337.427623] __do_softirq+0x1a0/0x5c4
> [ 337.427628] irq_exit+0x110/0x140
> [ 337.427633] handle_domain_irq+0xa4/0xe0
> [ 337.427640] gic_handle_irq+0x64/0x160
> [ 337.427644] call_on_irq_stack+0x20/0x4c
> [ 337.427649] do_interrupt_handler+0x7c/0x90
> [ 337.427654] el1_interrupt+0x30/0x80
> [ 337.427659] el1h_64_irq_handler+0x18/0x30
> [ 337.427663] el1h_64_irq+0x7c/0x80
> [ 337.427667] cpuidle_enter_state+0xe4/0x540
> [ 337.427674] cpuidle_enter+0x54/0x80
> [ 337.427679] do_idle+0x2e0/0x380
> [ 337.427685] cpu_startup_entry+0x2c/0x70
> [ 337.427690] rest_init+0x114/0x130
> [ 337.427695] arch_call_rest_init+0x18/0x24
> [ 337.427702] start_kernel+0x380/0x3b4
> [ 337.427706] __primary_switched+0xc0/0xc8
>
> Fixes: f46b195799b5 ("dmaengine: tegra-adma: Add support for Tegra210 ADMA")
>
> Signed-off-by: Sheetal <sheetal@nvidia.com>
> ---
> drivers/dma/tegra210-adma.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
Tiny nit-pick: there should be no blank line between the tags above
(i.e. between the Fixes: and Signed-off-by: lines).
Vinod, is that something you can fix up while applying, or do you want a
new patch for that?
In either case:
Acked-by: Thierry Reding <treding@nvidia.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] dmaengine: tegra-adma: Fix use-after-free
2025-11-27 9:25 ` Thierry Reding
@ 2025-12-16 15:23 ` Vinod Koul
0 siblings, 0 replies; 4+ messages in thread
From: Vinod Koul @ 2025-12-16 15:23 UTC (permalink / raw)
To: Thierry Reding
Cc: Sheetal ., ldewangan, jonathanh, dmaengine, linux-tegra,
linux-kernel
On 27-11-25, 10:25, Thierry Reding wrote:
> On Mon, Nov 10, 2025 at 07:54:45PM +0530, Sheetal . wrote:
>
> Tiny nit-pick: there should be no blank line between the tags above
> (i.e. between the Fixes: and Signed-off-by: lines).
>
> Vinod, is that something you can fix up while applying, or do you want a
> new patch for that?
Yep, fixed that
--
~Vinod
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] dmaengine: tegra-adma: Fix use-after-free
2025-11-10 14:24 [PATCH] dmaengine: tegra-adma: Fix use-after-free Sheetal .
2025-11-27 9:25 ` Thierry Reding
@ 2025-12-16 16:56 ` Vinod Koul
1 sibling, 0 replies; 4+ messages in thread
From: Vinod Koul @ 2025-12-16 16:56 UTC (permalink / raw)
To: Sheetal .
Cc: ldewangan, jonathanh, thierry.reding, dmaengine, linux-tegra,
linux-kernel
On Mon, 10 Nov 2025 19:54:45 +0530, Sheetal . wrote:
> A use-after-free bug exists in the Tegra ADMA driver when audio streams
> are terminated, particularly during XRUN conditions. The issue occurs
> when the DMA buffer is freed by tegra_adma_terminate_all() before the
> vchan completion tasklet finishes accessing it.
>
> The race condition follows this sequence:
>
> [...]
Applied, thanks!
[1/1] dmaengine: tegra-adma: Fix use-after-free
commit: 2efd07a7c36949e6fa36a69183df24d368bf9e96
Best regards,
--
~Vinod
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-12-16 16:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-10 14:24 [PATCH] dmaengine: tegra-adma: Fix use-after-free Sheetal .
2025-11-27 9:25 ` Thierry Reding
2025-12-16 15:23 ` Vinod Koul
2025-12-16 16:56 ` Vinod Koul
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox