]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.249/spi-bcm2835aux-fix-use-after-free-on-unbind.patch
6.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.249 / spi-bcm2835aux-fix-use-after-free-on-unbind.patch
CommitLineData
84ab5c28
GKH
1From foo@baz Fri Dec 11 03:42:15 PM CET 2020
2From: Lukas Wunner <lukas@wunner.de>
3Date: Thu, 10 Dec 2020 20:20:01 +0100
4Subject: spi: bcm2835aux: Fix use-after-free on unbind
5To: Greg Kroah-Hartman <gregkh@linuxfoundation.com>
6Cc: Mark Brown <broonie@kernel.org>, Sudip Mukherjee <sudipm.mukherjee@gmail.com>, Sasha Levin <sashal@kernel.org>, Nathan Chancellor <natechancellor@gmail.com>, stable@vger.kernel.org
7Message-ID: <6a940079e894346e8ee00878ef844decd216e695.1607626808.git.lukas@wunner.de>
8
9From: Lukas Wunner <lukas@wunner.de>
10
11[ Upstream commit e13ee6cc4781edaf8c7321bee19217e3702ed481 ]
12
13bcm2835aux_spi_remove() accesses the driver's private data after calling
14spi_unregister_master() even though that function releases the last
15reference on the spi_master and thereby frees the private data.
16
17Fix by switching over to the new devm_spi_alloc_master() helper which
18keeps the private data accessible until the driver has unbound.
19
20Fixes: b9dd3f6d4172 ("spi: bcm2835aux: Fix controller unregister order")
21Signed-off-by: Lukas Wunner <lukas@wunner.de>
22Cc: <stable@vger.kernel.org> # v4.4+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
23Cc: <stable@vger.kernel.org> # v4.4+: b9dd3f6d4172: spi: bcm2835aux: Fix controller unregister order
24Cc: <stable@vger.kernel.org> # v4.4+
25Link: https://lore.kernel.org/r/b290b06357d0c0bdee9cecc539b840a90630f101.1605121038.git.lukas@wunner.de
26Signed-off-by: Mark Brown <broonie@kernel.org>
27Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28---
29 drivers/spi/spi-bcm2835aux.c | 18 ++++++------------
30 1 file changed, 6 insertions(+), 12 deletions(-)
31
32--- a/drivers/spi/spi-bcm2835aux.c
33+++ b/drivers/spi/spi-bcm2835aux.c
34@@ -381,7 +381,7 @@ static int bcm2835aux_spi_probe(struct p
35 unsigned long clk_hz;
36 int err;
37
38- master = spi_alloc_master(&pdev->dev, sizeof(*bs));
39+ master = devm_spi_alloc_master(&pdev->dev, sizeof(*bs));
40 if (!master) {
41 dev_err(&pdev->dev, "spi_alloc_master() failed\n");
42 return -ENOMEM;
43@@ -411,30 +411,26 @@ static int bcm2835aux_spi_probe(struct p
44 /* the main area */
45 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
46 bs->regs = devm_ioremap_resource(&pdev->dev, res);
47- if (IS_ERR(bs->regs)) {
48- err = PTR_ERR(bs->regs);
49- goto out_master_put;
50- }
51+ if (IS_ERR(bs->regs))
52+ return PTR_ERR(bs->regs);
53
54 bs->clk = devm_clk_get(&pdev->dev, NULL);
55 if ((!bs->clk) || (IS_ERR(bs->clk))) {
56- err = PTR_ERR(bs->clk);
57 dev_err(&pdev->dev, "could not get clk: %d\n", err);
58- goto out_master_put;
59+ return PTR_ERR(bs->clk);
60 }
61
62 bs->irq = platform_get_irq(pdev, 0);
63 if (bs->irq <= 0) {
64 dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq);
65- err = bs->irq ? bs->irq : -ENODEV;
66- goto out_master_put;
67+ return bs->irq ? bs->irq : -ENODEV;
68 }
69
70 /* this also enables the HW block */
71 err = clk_prepare_enable(bs->clk);
72 if (err) {
73 dev_err(&pdev->dev, "could not prepare clock: %d\n", err);
74- goto out_master_put;
75+ return err;
76 }
77
78 /* just checking if the clock returns a sane value */
79@@ -467,8 +463,6 @@ static int bcm2835aux_spi_probe(struct p
80
81 out_clk_disable:
82 clk_disable_unprepare(bs->clk);
83-out_master_put:
84- spi_master_put(master);
85 return err;
86 }
87