From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from m16.mail.126.com (m16.mail.126.com [220.197.31.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70D11344030; Thu, 9 Jul 2026 02:40:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.9 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783564850; cv=none; b=Agrvet2X+fgyoV8z0QHEB9Jkb7jIWk/E8lPv0Uhgkvr+FypFpZKjCWBQSHsdu6NzJh65dVm8RcLnOHsYIeritnzrLt+L/D3B/B4rRQE7by/lnjYTMVKEGhtPtWh7DHwKJhgWIs0K/RuIhk4k6okWLXSo4RqXYnqvHniwupE9O3M= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783564850; c=relaxed/simple; bh=Skmf/zDz1zq2Niv5wCxgCKxzeoR+qq+iPrCOJJKqjjQ=; h=Message-ID:Date:From:MIME-Version:To:CC:Subject:References: In-Reply-To:Content-Type; b=PsP+v5z1oloqRDspacM15C5aPdg2BQI6uXjwV00e8qsW3Vro7GIgjxR+1pRYBrPOdro+aCa+tDRD2ecizv94kv3nT5JmbTQfY3ip3blYKj2XsqVLDEkljF078YUYGjCLl3sW4Gy3NEOUJSfutVuD5ZM3KBRbCjibHBEREfxXZYY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=126.com; spf=pass smtp.mailfrom=126.com; dkim=pass (1024-bit key) header.d=126.com header.i=@126.com header.b=W04D3AYD; arc=none smtp.client-ip=220.197.31.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=126.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=126.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=126.com header.i=@126.com header.b="W04D3AYD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=Message-ID:Date:From:MIME-Version:To:Subject: Content-Type; bh=zPzUjVYeTGVy0p5nTu0E1LwAP36Ua88/dAXmfMtmXgg=; b=W04D3AYDk7sFoPiHa+PV8e+zfacdmjnjWg/9sWyINApP/QihEQVfqN8dojbKek YDuJ9uy9B3Mt+g4MGrNgcyTQDEcx+uyE6Jcs3ocbpYsNao+Hy7UAVxbD2gXs2vaw w4SpFujtnuCBegGhgXSEC5kWCm+oL5aUTgXbaUkZ+fl3k= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g0-4 (Coremail) with SMTP id _____wDnL0z5CU9qxiduDA--.8579S2; Thu, 09 Jul 2026 10:39:54 +0800 (CST) Message-ID: <6A4F09E8.8040807@126.com> Date: Thu, 09 Jul 2026 10:39:36 +0800 From: Hongling Zeng User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: Frank Li , Hongling Zeng CC: ludovic.desroches@microchip.com, vkoul@kernel.org, Frank.Li@kernel.org, tudor.ambarus@linaro.org, nicolas.ferre@microchip.com, linux-arm-kernel@lists.infradead.org, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, sashiko-bot@kernel.org Subject: Re: [PATCH v4] dma: at_hdmac: Fix use-after-free by proper tasklet cleanup References: <20260708025959.40283-1-zenghongling@kylinos.cn> In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-CM-TRANSID:_____wDnL0z5CU9qxiduDA--.8579S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxuF47ZFy3KrWUJF13ur4fAFb_yoWrZr4fpr WUJFWYkrW0qrn09Fnruw4kua4Fva1Sqw4SgrW7Kw13A34YvrnYyFW8Cw1UWFZxAFykXr1S gFZ8tFyrur1rJr7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07j4Hq7UUUUU= X-CM-SenderInfo: x2kr0wpolqwiqxrzqiyswou0bp/xtbBrhruv2pPCfq6pQAA3s 在 2026年07月09日 05:32, Frank Li 写道: > On Wed, Jul 08, 2026 at 10:59:59AM +0800, Hongling Zeng wrote: >> Current cleanup paths have a use-after-free vulnerability: >> - vchan_init() creates tasklets that access at_dma_chan memory >> - free_irq() only waits for IRQ handler, NOT tasklets >> - atdma is devm-managed and freed after probe/remove >> - Running tasklets accessing freed memory → Use-After-Free! >> >> The fix requires careful ordering: >> - free_irq() FIRST to synchronize with running IRQ handlers and prevent >> them from scheduling new tasklets >> - Then kill tasklets to wait for already-scheduled ones to complete >> - Only then free other resources >> >> Fixes: ac803b56860f ("dmaengine: at_hdmac: Convert driver to use virt-dma") >> Reported-by: sashiko-bot@kernel.org >> Closes: https://lore.kernel.org/all/20260604073945.54B311F00898@smtp.kernel.org/ >> Signed-off-by: Hongling Zeng >> >> --- >> Change in v4: >> - Fix error path fallthrough causing double-free_irq() >> - Use channel iteration index (chan_id not initialized before registration) >> - Remove unnecessary defensive checks >> --- >> drivers/dma/at_hdmac.c | 31 ++++++++++++++++++++++--------- >> 1 file changed, 22 insertions(+), 9 deletions(-) >> >> diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c >> index e5b30a57c477..044a0fb38b7a 100644 >> --- a/drivers/dma/at_hdmac.c >> +++ b/drivers/dma/at_hdmac.c >> @@ -1940,6 +1940,20 @@ static void at_dma_off(struct at_dma *atdma) >> cpu_relax(); >> } >> >> +static void at_dma_cleanup_channels(struct at_dma *atdma) >> +{ >> + struct dma_chan *chan, *_chan; >> + int i = 0; >> + >> + list_for_each_entry_safe(chan, _chan, &atdma->dma_device.channels, >> + device_node) { >> + /* Disable interrupts */ >> + atc_disable_chan_irq(atdma, i++); >> + tasklet_kill(&to_at_dma_chan(chan)->vc.task); >> + list_del(&chan->device_node); >> + } >> +} >> + >> static int __init at_dma_probe(struct platform_device *pdev) >> { >> struct at_dma *atdma; >> @@ -2105,12 +2119,17 @@ static int __init at_dma_probe(struct platform_device *pdev) >> err_of_dma_controller_register: >> dma_async_device_unregister(&atdma->dma_device); >> err_dma_async_device_register: >> + free_irq(platform_get_irq(pdev, 0), atdma); >> + at_dma_cleanup_channels(atdma); >> dma_pool_destroy(atdma->memset_pool); >> + dma_pool_destroy(atdma->lli_pool); >> + goto err_clk; > I forget the reason why need goto here. Can you call disable_irq() or > disable hardware irq and call synchronize_irq() at free_irq() place. then > goto can fallback to below clean up code > > Frank Thank you for the suggestion. I've updated to v6 following your advice: - Replaced free_irq() with disable_irq() to allow fallthrough without goto - free_irq() is now called only once at err_desc_pool_create label The new approach ensures IRQ handler cannot schedule tasklets before tasklet_kill(), then free_irq() handles the actual release. Please help to review again. Thanks! > >> err_memset_pool_create: >> dma_pool_destroy(atdma->lli_pool); >> err_desc_pool_create: >> free_irq(platform_get_irq(pdev, 0), atdma); >> err_irq: >> +err_clk: >> clk_disable_unprepare(atdma->clk); >> return err; >> } >> @@ -2118,23 +2137,17 @@ static int __init at_dma_probe(struct platform_device *pdev) >> static void at_dma_remove(struct platform_device *pdev) >> { >> struct at_dma *atdma = platform_get_drvdata(pdev); >> - struct dma_chan *chan, *_chan; >> >> at_dma_off(atdma); >> if (pdev->dev.of_node) >> of_dma_controller_free(pdev->dev.of_node); >> dma_async_device_unregister(&atdma->dma_device); >> >> - dma_pool_destroy(atdma->memset_pool); >> - dma_pool_destroy(atdma->lli_pool); >> free_irq(platform_get_irq(pdev, 0), atdma); >> >> - list_for_each_entry_safe(chan, _chan, &atdma->dma_device.channels, >> - device_node) { >> - /* Disable interrupts */ >> - atc_disable_chan_irq(atdma, chan->chan_id); >> - list_del(&chan->device_node); >> - } >> + at_dma_cleanup_channels(atdma); >> + dma_pool_destroy(atdma->memset_pool); >> + dma_pool_destroy(atdma->lli_pool); >> >> clk_disable_unprepare(atdma->clk); >> } >> -- >> 2.25.1 >>