Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp3823038ybi; Mon, 29 Jul 2019 13:19:02 -0700 (PDT) X-Google-Smtp-Source: APXvYqz7XqAsSLiGNL99rSWn5VXeMwFzLV4ahwYBHrm4cbpAN/nWCq9yiWHJENb1UMZ0bU1AZr6X X-Received: by 2002:a17:90a:db08:: with SMTP id g8mr109811706pjv.39.1564431542465; Mon, 29 Jul 2019 13:19:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564431542; cv=none; d=google.com; s=arc-20160816; b=XQL18xsx6nLgdxKGuNCpCSCjB5wPZ66581WR2mAaz1Xfs0ilf91waw8xC6zdMqui8C LKVnJronmQXzyrRx+Y3cEQcZaGlcE2pQerT6yFvp/vbNr+52WbQi+3E/UbeW8n64gOV/ FxxB9+rr29LaU0DvtEiF1BD5pfWLHb992GgzQoe96VkIJnPSZ5oOOoKRx+WSuDz0w++m f0leZdTDWIWwkzTLcUvabBBuo6nJZWqKiofqSAPMJ/IwwDS4dti6K1EBXP33Ao2PyMRj +1Xsl+28zkWgtDoj8RbA8hqQQIQtiBvAw3bz6cU65P8EE0oQcnxuZWH3dIGW904AS47m eJNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=JbyxT1ZjVXPHNXZFj7FzaVF1fD7zaHOCQYPCGJh41x0=; b=GNRufLK0Q5EPnvzlijhlhJMKMxyPyZLg4QRZK4897ZlCvwVgWJ3+fnddxoXPKEfkI2 RuG3dNUcQM8nLb9k3tcX1srY2332krheqT52lYT34zYsJ1BEhA8ZC6C6/ehS4VTCMbFx MmHbkztF5vdrt2Njclx9KKaKXK56RVUj6Wg2FnWgkP74J9xktE//3zZZ014GlvWsFHMr aZ3rT7mPgn0HXdmjsYlMEzoSICVzzhpfB2F+/teC4FpabglOoJKqQM85fpZu1I1E3zK6 7ECkuD0Zj9iI7BwXZfWf7skOzbnwe4xAJEndXFLiPZ34GmPKQBKVsTyEsgJRp4fo1vwL Rohw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=dUHDWeDT; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w14si29948884pjn.15.2019.07.29.13.18.46; Mon, 29 Jul 2019 13:19:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=dUHDWeDT; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729490AbfG2TYW (ORCPT + 99 others); Mon, 29 Jul 2019 15:24:22 -0400 Received: from mail.kernel.org ([198.145.29.99]:36516 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387561AbfG2TYR (ORCPT ); Mon, 29 Jul 2019 15:24:17 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 2F30D2070B; Mon, 29 Jul 2019 19:24:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1564428256; bh=G2bbweMEWk37RuRfeZkhAnlhnD8IaKCChWQMszFGcC8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dUHDWeDTQ+SFvMJBVMzwmyug92EKQFA0NSlA2qf8rsGX4MfAx1CfXiCDvSuggka6z Gg3R/fDohqxxZlEvyD4OijFydlvv01v0UtSar+8aS7jlh/z6AaWTgrHD4dqBkwSPND x99xD0bGQeTAwrAz1L12EfrkqCE51TwfYy75zWk4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Sven Van Asbroeck , Robin Gong , Vinod Koul , Sasha Levin Subject: [PATCH 4.14 005/293] dmaengine: imx-sdma: fix use-after-free on probe error path Date: Mon, 29 Jul 2019 21:18:16 +0200 Message-Id: <20190729190820.752569822@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190729190820.321094988@linuxfoundation.org> References: <20190729190820.321094988@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [ Upstream commit 2b8066c3deb9140fdf258417a51479b2aeaa7622 ] If probe() fails anywhere beyond the point where sdma_get_firmware() is called, then a kernel oops may occur. Problematic sequence of events: 1. probe() calls sdma_get_firmware(), which schedules the firmware callback to run when firmware becomes available, using the sdma instance structure as the context 2. probe() encounters an error, which deallocates the sdma instance structure 3. firmware becomes available, firmware callback is called with deallocated sdma instance structure 4. use after free - kernel oops ! Solution: only attempt to load firmware when we're certain that probe() will succeed. This guarantees that the firmware callback's context will remain valid. Note that the remove() path is unaffected by this issue: the firmware loader will increment the driver module's use count, ensuring that the module cannot be unloaded while the firmware callback is pending or running. Signed-off-by: Sven Van Asbroeck Reviewed-by: Robin Gong [vkoul: fixed braces for if condition] Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/imx-sdma.c | 48 ++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index b8e7c2d8915e..0fc12a8783e3 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1821,27 +1821,6 @@ static int sdma_probe(struct platform_device *pdev) if (pdata && pdata->script_addrs) sdma_add_scripts(sdma, pdata->script_addrs); - if (pdata) { - ret = sdma_get_firmware(sdma, pdata->fw_name); - if (ret) - dev_warn(&pdev->dev, "failed to get firmware from platform data\n"); - } else { - /* - * Because that device tree does not encode ROM script address, - * the RAM script in firmware is mandatory for device tree - * probe, otherwise it fails. - */ - ret = of_property_read_string(np, "fsl,sdma-ram-script-name", - &fw_name); - if (ret) - dev_warn(&pdev->dev, "failed to get firmware name\n"); - else { - ret = sdma_get_firmware(sdma, fw_name); - if (ret) - dev_warn(&pdev->dev, "failed to get firmware from device tree\n"); - } - } - sdma->dma_device.dev = &pdev->dev; sdma->dma_device.device_alloc_chan_resources = sdma_alloc_chan_resources; @@ -1883,6 +1862,33 @@ static int sdma_probe(struct platform_device *pdev) of_node_put(spba_bus); } + /* + * Kick off firmware loading as the very last step: + * attempt to load firmware only if we're not on the error path, because + * the firmware callback requires a fully functional and allocated sdma + * instance. + */ + if (pdata) { + ret = sdma_get_firmware(sdma, pdata->fw_name); + if (ret) + dev_warn(&pdev->dev, "failed to get firmware from platform data\n"); + } else { + /* + * Because that device tree does not encode ROM script address, + * the RAM script in firmware is mandatory for device tree + * probe, otherwise it fails. + */ + ret = of_property_read_string(np, "fsl,sdma-ram-script-name", + &fw_name); + if (ret) { + dev_warn(&pdev->dev, "failed to get firmware name\n"); + } else { + ret = sdma_get_firmware(sdma, fw_name); + if (ret) + dev_warn(&pdev->dev, "failed to get firmware from device tree\n"); + } + } + return 0; err_register: -- 2.20.1