Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp36347pxu; Thu, 10 Dec 2020 17:29:42 -0800 (PST) X-Google-Smtp-Source: ABdhPJxjOBTgrimO/carECVnG1fPYeAzqG2EEy6U9WTPKK4TRuSbUCgU67F8/rAJxDfIoQ2emkrU X-Received: by 2002:aa7:c886:: with SMTP id p6mr9798564eds.352.1607650182363; Thu, 10 Dec 2020 17:29:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1607650182; cv=none; d=google.com; s=arc-20160816; b=Dxa+pI1V6mQSCOZTI8kqZnGJZSQsp4XbsG0X/isvIbzpzj1z8N9Q4fWyYgD0NlbbyE wuR1KCB31JAdFGyrZ8E6ITkzDXsT7QpavHtzmGi19NNQTQlsTuhNcgPB4oa9yig3k7YK 1S4bBo75958cCuZn6dQggaRe83a/6Ko01FDydDCdFUR88dzxBf8lEuzw0KG5vf5LFx5y xfWVV8HkJ1mJXn4XF/T5ONm+nFBNA8M6T4hsNaGtk69P6X+EpUUwJzjx7pRAAtSyi27I 13nGIfmi4kWBr4lqQ03pU33DCJ3PayvZ/l7gJ2kvKmr2yIWPn9+qLoMrV7CGiFzSJVU5 Nuiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=ipQibeI9jQDLnpHr+6VggB+rhSGBrZ6QcwmgDwJ5VyQ=; b=drCR7Vi9UvsaS/U7oQyGgH3adT4OiRRuS6p3zuEumTm2QsEGI3Gs8XonwyAtmoqmCF tY43tF1vRjC1dzb0rdB05t9dNXd5Tm6D9pmtq+w6jWeb5Qg5YhJrcLypAQK7Z7eFOjo8 GhRV0cilKftU1dSDCnq4ZBL/o4LM49j9feIOIu0qDDivzK66pxJ69X2h5dbouI1q2kA4 tBxzYEQuQleqgnpEMfp92JRJcMnRNEFFo30rlaUHZVxhE0sO5p+3QzWkAODab0sORerv 1l0k6zb1saAaM2G6ii3L3lWkPxxhcZ/MuXOXK+MpsjZODxg0VvOZZCLbUBNY6Ug7QzQG eamw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e25si3947060edq.489.2020.12.10.17.29.19; Thu, 10 Dec 2020 17:29:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390534AbgLJOcK (ORCPT + 99 others); Thu, 10 Dec 2020 09:32:10 -0500 Received: from mail.kernel.org ([198.145.29.99]:38552 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390289AbgLJOad (ORCPT ); Thu, 10 Dec 2020 09:30:33 -0500 From: Greg Kroah-Hartman Authentication-Results: mail.kernel.org; dkim=permerror (bad message/signature format) To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lukas Wunner , Kamal Dasu , Florian Fainelli , Mark Brown Subject: [PATCH 4.9 38/45] spi: bcm-qspi: Fix use-after-free on unbind Date: Thu, 10 Dec 2020 15:26:52 +0100 Message-Id: <20201210142604.233206482@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201210142602.361598591@linuxfoundation.org> References: <20201210142602.361598591@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lukas Wunner [ Upstream commit 63c5395bb7a9777a33f0e7b5906f2c0170a23692 ] bcm_qspi_remove() calls spi_unregister_master() even though bcm_qspi_probe() calls devm_spi_register_master(). The spi_master is therefore unregistered and freed twice on unbind. Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound. While at it, fix an ordering issue in bcm_qspi_remove() wherein spi_unregister_master() is called after uninitializing the hardware, disabling the clock and freeing an IRQ data structure. The correct order is to call spi_unregister_master() *before* those teardown steps because bus accesses may still be ongoing until that function returns. Fixes: fa236a7ef240 ("spi: bcm-qspi: Add Broadcom MSPI driver") Signed-off-by: Lukas Wunner Cc: # v4.9+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: # v4.9+ Cc: Kamal Dasu Acked-by: Florian Fainelli Tested-by: Florian Fainelli Link: https://lore.kernel.org/r/5e31a9a59fd1c0d0b795b2fe219f25e5ee855f9d.1605121038.git.lukas@wunner.de Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-bcm-qspi.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -1185,7 +1185,7 @@ int bcm_qspi_probe(struct platform_devic if (!of_match_node(bcm_qspi_of_match, dev->of_node)) return -ENODEV; - master = spi_alloc_master(dev, sizeof(struct bcm_qspi)); + master = devm_spi_alloc_master(dev, sizeof(struct bcm_qspi)); if (!master) { dev_err(dev, "error allocating spi_master\n"); return -ENOMEM; @@ -1218,21 +1218,17 @@ int bcm_qspi_probe(struct platform_devic if (res) { qspi->base[MSPI] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[MSPI])) { - ret = PTR_ERR(qspi->base[MSPI]); - goto qspi_resource_err; - } + if (IS_ERR(qspi->base[MSPI])) + return PTR_ERR(qspi->base[MSPI]); } else { - goto qspi_resource_err; + return 0; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); if (res) { qspi->base[BSPI] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[BSPI])) { - ret = PTR_ERR(qspi->base[BSPI]); - goto qspi_resource_err; - } + if (IS_ERR(qspi->base[BSPI])) + return PTR_ERR(qspi->base[BSPI]); qspi->bspi_mode = true; } else { qspi->bspi_mode = false; @@ -1243,18 +1239,14 @@ int bcm_qspi_probe(struct platform_devic res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg"); if (res) { qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[CHIP_SELECT])) { - ret = PTR_ERR(qspi->base[CHIP_SELECT]); - goto qspi_resource_err; - } + if (IS_ERR(qspi->base[CHIP_SELECT])) + return PTR_ERR(qspi->base[CHIP_SELECT]); } qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), GFP_KERNEL); - if (!qspi->dev_ids) { - ret = -ENOMEM; - goto qspi_resource_err; - } + if (!qspi->dev_ids) + return -ENOMEM; for (val = 0; val < num_irqs; val++) { irq = -1; @@ -1330,7 +1322,7 @@ int bcm_qspi_probe(struct platform_devic qspi->xfer_mode.addrlen = -1; qspi->xfer_mode.hp = -1; - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret < 0) { dev_err(dev, "can't register master\n"); goto qspi_reg_err; @@ -1343,8 +1335,6 @@ qspi_reg_err: clk_disable_unprepare(qspi->clk); qspi_probe_err: kfree(qspi->dev_ids); -qspi_resource_err: - spi_master_put(master); return ret; } /* probe function to be called by SoC specific platform driver probe */ @@ -1355,10 +1345,10 @@ int bcm_qspi_remove(struct platform_devi struct bcm_qspi *qspi = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); + spi_unregister_master(qspi->master); bcm_qspi_hw_uninit(qspi); clk_disable_unprepare(qspi->clk); kfree(qspi->dev_ids); - spi_unregister_master(qspi->master); return 0; }