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 X-Spam-Level: X-Spam-Status: No, score=-17.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D400C4338F for ; Tue, 10 Aug 2021 14:18:51 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 648C761008 for ; Tue, 10 Aug 2021 14:18:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 648C761008 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=ye/hkkMQin5NUcuIfMASl2msi8bq9B4d4fQy1Jo64nA=; b=GcOYHcTSqJMDC5 xW2J1LaVycAuUSVYsxslXUCb67374xIMseBwiMglIdQm4X2NOPbDt7jrQ9GTq5RkoyzmGb+cbX51c lmqVe6ntK+73NOD/XPp6Ph8Vxh+RW8M/H37LFAzxbDFkKYSCxbVVdYdjBVcqOoPnmnI64D9Oi9SW2 gLPVSDOhuhO44YRjeO3UgNNhqTI2lQB2g4ImAdCH/5lFWTn6f/PlFR5xsXiXZ6X4uARnFOEL8atXh CfLP3GNOWOgBUNibv76oMjYUayJ+vGad1qYouzskjcUHcpfn/5Hh/HSwyfJMKFFVqlSCvVSY8uMT1 eSRaqdaZSG6l+XfnrZ5g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mDSXA-0046Pd-GK; Tue, 10 Aug 2021 14:15:12 +0000 Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mDSX6-0046PI-OA for linux-arm-kernel@lists.infradead.org; Tue, 10 Aug 2021 14:15:10 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1EB0260F41; Tue, 10 Aug 2021 14:15:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1628604907; bh=tHeW17I9H24bnFkW/B5efT8oDfZabpe5hHSdODE6ycU=; h=From:To:Cc:Subject:Date:From; b=FR4An9RJa2A2iScm2xUI1Jg1JcdKP2oYDb8SlbEynQM8/ZYBjAdWcW7zQTbK3EluF gyS6r3E9GKzFuHy6TtkMKFzBqy3HJhgTFvqb1NpDp/8FJaI/aEsKY/JWQDThU1JEp1 /KfA0WyDJkF6/6yKK+oc8dM8dvIm9UHXv1uYlcgOL/1x1gYrPb4wNytlbreHNOl6IZ fs9EpWhUwRpUdfQe9h1/C6rMVLmluNubZRxRcoyJfsk4FNPzCpgIxNcWrQZXZTypG1 AyiqHgfQ4lcibwbPlGDPbFAcDIPdmEanZWQlz7YgxX0bgcmz2gJGUbDl7ChvoD4wJE fggVVM8qi9ZOg== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Adrian Larumbe , Vinod Koul , Sasha Levin , dmaengine@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH AUTOSEL 5.13 01/24] dmaengine: xilinx_dma: Fix read-after-free bug when terminating transfers Date: Tue, 10 Aug 2021 10:14:42 -0400 Message-Id: <20210810141505.3117318-1-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210810_071508_865713_25B14D47 X-CRM114-Status: GOOD ( 13.23 ) 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: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Adrian Larumbe [ Upstream commit 7dd2dd4ff9f3abda601f22b9d01441a0869d20d7 ] When user calls dmaengine_terminate_sync, the driver will clean up any remaining descriptors for all the pending or active transfers that had previously been submitted. However, this might happen whilst the tasklet is invoking the DMA callback for the last finished transfer, so by the time it returns and takes over the channel's spinlock, the list of completed descriptors it was traversing is no longer valid. This leads to a read-after-free situation. Fix it by signalling whether a user-triggered termination has happened by means of a boolean variable. Signed-off-by: Adrian Larumbe Link: https://lore.kernel.org/r/20210706234338.7696-3-adrian.martinezlarumbe@imgtec.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/xilinx/xilinx_dma.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 75c0b8e904e5..4b9530a7bf65 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -394,6 +394,7 @@ struct xilinx_dma_tx_descriptor { * @genlock: Support genlock mode * @err: Channel has errors * @idle: Check for channel idle + * @terminating: Check for channel being synchronized by user * @tasklet: Cleanup work after irq * @config: Device configuration info * @flush_on_fsync: Flush on Frame sync @@ -431,6 +432,7 @@ struct xilinx_dma_chan { bool genlock; bool err; bool idle; + bool terminating; struct tasklet_struct tasklet; struct xilinx_vdma_config config; bool flush_on_fsync; @@ -1049,6 +1051,13 @@ static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) /* Run any dependencies, then free the descriptor */ dma_run_dependencies(&desc->async_tx); xilinx_dma_free_tx_descriptor(chan, desc); + + /* + * While we ran a callback the user called a terminate function, + * which takes care of cleaning up any remaining descriptors + */ + if (chan->terminating) + break; } spin_unlock_irqrestore(&chan->lock, flags); @@ -1965,6 +1974,8 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx) if (desc->cyclic) chan->cyclic = true; + chan->terminating = false; + spin_unlock_irqrestore(&chan->lock, flags); return cookie; @@ -2436,6 +2447,7 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan) xilinx_dma_chan_reset(chan); /* Remove and free all of the descriptors in the lists */ + chan->terminating = true; xilinx_dma_free_descriptors(chan); chan->idle = true; -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel