From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 97450C43458 for ; Thu, 9 Jul 2026 02:40:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:In-Reply-To:References:Subject:CC:To:MIME-Version:From:Date: Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=zPzUjVYeTGVy0p5nTu0E1LwAP36Ua88/dAXmfMtmXgg=; b=OTnrbGYb6oHb1pIzlhPOI4/2pv McAEN3utdvFlwdy7YXRjgG6+L6NID5Y6GHS13XtOuARs/K2OJDq3A9s9T+Uu87kTxEy5wAbkcot5P /rMgSjPWf8SvpAxsTcMG+NGKDxva6EGKmYcdSJ41hB3XXAJcY7HK9PpsyrygYYiBTj9i88BQ8ubJz VxHkm0dBrXO4KZp1L8liRp5bOMEz3TvtRFISnpLJV8wQ2ZHkiA9xnnwgOcgsOWCfsOq1JVCxtBJEC 93u+E4UxKlFewoyjReh/0n1zN5nx78DsWT0AG02tKQPLSzrkoHoWMXNz/ptY3xrJlAUczDf7fK3D0 5QokTkvQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1whegc-00000000rD7-19F5; Thu, 09 Jul 2026 02:40:26 +0000 Received: from m16.mail.126.com ([220.197.31.6]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1whegZ-00000000rB0-0GBI for linux-arm-kernel@lists.infradead.org; Thu, 09 Jul 2026 02:40:24 +0000 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 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-Originating-IP: [112.64.161.44] X-CM-SenderInfo: x2kr0wpolqwiqxrzqiyswou0bp/xtbBrhruv2pPCfq6pQAA3s X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260708_194023_568002_AE064AB8 X-CRM114-Status: GOOD ( 18.50 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org 在 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 >>