linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH] spi: fix use-after-free of the add_lock mutex
@ 2021-11-10 16:08 Michael Walle
  2021-11-10 16:27 ` Mark Brown
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Michael Walle @ 2021-11-10 16:08 UTC (permalink / raw)
  To: linux-spi, linux-kernel
  Cc: Mark Brown, Uwe Kleine-König, Vladimir Oltean, Michael Walle

Commit 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on
SPI buses") introduced a per-controller mutex. But mutex_unlock() of
said lock is called after the controller is already freed:

  spi_unregister_controller(ctlr)
   -> put_device(&ctlr->dev)
    -> spi_controller_release(dev)
  mutex_unlock(&ctrl->add_lock)

Move the put_device() after the mutex_unlock().

Fixes: 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on SPI buses")
Signed-off-by: Michael Walle <michael@walle.cc>
---
I'm not sure if this is the correct fix. I don't know if the put_device()
will have to be protected by the add_lock (remember before, the add_lock
was a global lock).

For reference, the kernel oops is:
[   20.242505] Unable to handle kernel paging request at virtual address 0042a2203dc65260
[   20.250468] Mem abort info:
[   20.253270]   ESR = 0x96000044
[   20.256332]   EC = 0x25: DABT (current EL), IL = 32 bits
[   20.261662]   SET = 0, FnV = 0
[   20.264723]   EA = 0, S1PTW = 0
[   20.267869]   FSC = 0x04: level 0 translation fault
[   20.272764] Data abort info:
[   20.275646]   ISV = 0, ISS = 0x00000044
[   20.279494]   CM = 0, WnR = 1
[   20.282469] [0042a2203dc65260] address between user and kernel address ranges
[   20.289632] Internal error: Oops: 96000044 [#1] SMP
[   20.294525] Modules linked in:
[   20.297586] CPU: 1 PID: 1546 Comm: init Not tainted 5.15.0-next-20211109+ #1307
[   20.304919] Hardware name: Kontron KBox A-230-LS (DT)
[   20.309983] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   20.316968] pc : queued_spin_lock_slowpath+0x1a8/0x3a0
[   20.322127] lr : __mutex_unlock_slowpath.constprop.0+0x180/0x190
[   20.328156] sp : ffff800013c23b80
[   20.331475] x29: ffff800013c23b80 x28: ffff002003941040 x27: 0000000000000000
[   20.338639] x26: ffff002000e49c90 x25: ffff80001167de48 x24: ffff800011f55578
[   20.345802] x23: ffff002002b1d350 x22: 0000000000000002 x21: 0000000000000001
[   20.352964] x20: ffff800013c23bb8 x19: ffff002002b1d350 x18: 00000000fffffffb
[   20.360126] x17: 0000000000000001 x16: 0000000000000001 x15: 0000000000000020
[   20.367288] x14: 0000000000000001 x13: 0000000000000000 x12: ffff002002c27938
[   20.374450] x11: ffff002002c27908 x10: 0000000000000000 x9 : 0000000000080000
[   20.381612] x8 : 0000000000000000 x7 : ffff00207f7b7a00 x6 : ffff8000119d1a00
[   20.388774] x5 : ffff00207f7b7a00 x4 : 504322202c293830 x3 : ffff002002b1d358
[   20.395936] x2 : ffff8000119d1a30 x1 : ffff8000119d1a30 x0 : ffff00207f7b7a08
[   20.403098] Call trace:
[   20.405546]  queued_spin_lock_slowpath+0x1a8/0x3a0
[   20.410352]  mutex_unlock+0x5c/0x70
[   20.413849]  spi_unregister_controller+0xf0/0x170
[   20.418568]  dspi_remove+0x28/0xb0
[   20.421978]  dspi_shutdown+0x1c/0x30
[   20.425561]  platform_shutdown+0x30/0x40
[   20.429495]  device_shutdown+0x14c/0x420
[   20.433427]  __do_sys_reboot+0x214/0x29c
[   20.437361]  __arm64_sys_reboot+0x30/0x40
[   20.441380]  invoke_syscall+0x50/0x120
[   20.445140]  el0_svc_common.constprop.0+0x58/0x190
[   20.449944]  do_el0_svc+0x30/0x94
[   20.453267]  el0_svc+0x20/0x90
[   20.456327]  el0t_64_sync_handler+0x1a4/0x1b0
[   20.460694]  el0t_64_sync+0x1a0/0x1a4
[   20.464368] Code: 910020e0 8b0200c2 f861d884 aa0203e1 (f8246827) 
[   20.470479] ---[ end trace 9ee0c21f9e4bc5d5 ]---
[   21.475251] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
[   21.482940] Kernel Offset: disabled
[   21.486433] CPU features: 0x2,000001c2,40000846
[   21.490976] Memory Limit: none
[   21.494036] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000 ]---

 drivers/spi/spi.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index b23e675953e1..fdd530b150a7 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3099,12 +3099,6 @@ void spi_unregister_controller(struct spi_controller *ctlr)
 
 	device_del(&ctlr->dev);
 
-	/* Release the last reference on the controller if its driver
-	 * has not yet been converted to devm_spi_alloc_master/slave().
-	 */
-	if (!ctlr->devm_allocated)
-		put_device(&ctlr->dev);
-
 	/* free bus id */
 	mutex_lock(&board_lock);
 	if (found == ctlr)
@@ -3113,6 +3107,12 @@ void spi_unregister_controller(struct spi_controller *ctlr)
 
 	if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
 		mutex_unlock(&ctlr->add_lock);
+
+	/* Release the last reference on the controller if its driver
+	 * has not yet been converted to devm_spi_alloc_master/slave().
+	 */
+	if (!ctlr->devm_allocated)
+		put_device(&ctlr->dev);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_controller);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH] spi: fix use-after-free of the add_lock mutex
  2021-11-10 16:08 [RFC PATCH] spi: fix use-after-free of the add_lock mutex Michael Walle
@ 2021-11-10 16:27 ` Mark Brown
  2021-11-10 16:30   ` Michael Walle
  2021-11-10 16:49 ` Andy Shevchenko
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Mark Brown @ 2021-11-10 16:27 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-spi, linux-kernel, Uwe Kleine-König, Vladimir Oltean

[-- Attachment #1: Type: text/plain, Size: 1108 bytes --]

On Wed, Nov 10, 2021 at 05:08:36PM +0100, Michael Walle wrote:
> Commit 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on
> SPI buses") introduced a per-controller mutex. But mutex_unlock() of
> said lock is called after the controller is already freed:
> 
>   spi_unregister_controller(ctlr)
>    -> put_device(&ctlr->dev)
>     -> spi_controller_release(dev)
>   mutex_unlock(&ctrl->add_lock)
> 
> Move the put_device() after the mutex_unlock().

Do we even need to unlock the mutex here?

> 
> For reference, the kernel oops is:
> [   20.242505] Unable to handle kernel paging request at virtual address 0042a2203dc65260
> [   20.250468] Mem abort info:
> [   20.253270]   ESR = 0x96000044

Please think hard before including complete backtraces in upstream
reports, they are very large and contain almost no useful information
relative to their size so often obscure the relevant content in your
message. If part of the backtrace is usefully illustrative (it often is
for search engines if nothing else) then it's usually better to pull out
the relevant sections.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH] spi: fix use-after-free of the add_lock mutex
  2021-11-10 16:27 ` Mark Brown
@ 2021-11-10 16:30   ` Michael Walle
  2021-11-10 16:39     ` Mark Brown
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Walle @ 2021-11-10 16:30 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, linux-kernel, Uwe Kleine-König, Vladimir Oltean

Am 2021-11-10 17:27, schrieb Mark Brown:
>> For reference, the kernel oops is:
>> [   20.242505] Unable to handle kernel paging request at virtual 
>> address 0042a2203dc65260
>> [   20.250468] Mem abort info:
>> [   20.253270]   ESR = 0x96000044
> 
> Please think hard before including complete backtraces in upstream
> reports, they are very large and contain almost no useful information
> relative to their size so often obscure the relevant content in your
> message. If part of the backtrace is usefully illustrative (it often is
> for search engines if nothing else) then it's usually better to pull 
> out
> the relevant sections.

It was in the comments section of the patch, for exactly this purpose.
That's how you're doing it, no?

-michael

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH] spi: fix use-after-free of the add_lock mutex
  2021-11-10 16:30   ` Michael Walle
@ 2021-11-10 16:39     ` Mark Brown
  0 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2021-11-10 16:39 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-spi, linux-kernel, Uwe Kleine-König, Vladimir Oltean

[-- Attachment #1: Type: text/plain, Size: 979 bytes --]

On Wed, Nov 10, 2021 at 05:30:48PM +0100, Michael Walle wrote:
> Am 2021-11-10 17:27, schrieb Mark Brown:

> > > For reference, the kernel oops is:
> > > [   20.242505] Unable to handle kernel paging request at virtual
> > > address 0042a2203dc65260
> > > [   20.250468] Mem abort info:
> > > [   20.253270]   ESR = 0x96000044

> > Please think hard before including complete backtraces in upstream
> > reports, they are very large and contain almost no useful information
> > relative to their size so often obscure the relevant content in your
> > message. If part of the backtrace is usefully illustrative (it often is
> > for search engines if nothing else) then it's usually better to pull out
> > the relevant sections.

> It was in the comments section of the patch, for exactly this purpose.
> That's how you're doing it, no?

That helps with what ends up in git but it's still including multiple
screenfuls of noise in the email which is where the usability problem
is.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH] spi: fix use-after-free of the add_lock mutex
  2021-11-10 16:08 [RFC PATCH] spi: fix use-after-free of the add_lock mutex Michael Walle
  2021-11-10 16:27 ` Mark Brown
@ 2021-11-10 16:49 ` Andy Shevchenko
  2021-11-10 17:28 ` Uwe Kleine-König
  2021-11-11  5:19 ` Lukas Wunner
  3 siblings, 0 replies; 7+ messages in thread
From: Andy Shevchenko @ 2021-11-10 16:49 UTC (permalink / raw)
  To: Michael Walle, Lukas Wunner
  Cc: linux-spi, Linux Kernel Mailing List, Mark Brown,
	Uwe Kleine-König, Vladimir Oltean

On Wed, Nov 10, 2021 at 6:09 PM Michael Walle <michael@walle.cc> wrote:
>
> Commit 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on
> SPI buses") introduced a per-controller mutex. But mutex_unlock() of
> said lock is called after the controller is already freed:
>
>   spi_unregister_controller(ctlr)
>    -> put_device(&ctlr->dev)
>     -> spi_controller_release(dev)
>   mutex_unlock(&ctrl->add_lock)
>
> Move the put_device() after the mutex_unlock().

I have a déjà-vu feeling about this code (Cc Lukas).

>
> Fixes: 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on SPI buses")
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
> I'm not sure if this is the correct fix. I don't know if the put_device()
> will have to be protected by the add_lock (remember before, the add_lock
> was a global lock).
>
> For reference, the kernel oops is:
> [   20.242505] Unable to handle kernel paging request at virtual address 0042a2203dc65260
> [   20.250468] Mem abort info:
> [   20.253270]   ESR = 0x96000044
> [   20.256332]   EC = 0x25: DABT (current EL), IL = 32 bits
> [   20.261662]   SET = 0, FnV = 0
> [   20.264723]   EA = 0, S1PTW = 0
> [   20.267869]   FSC = 0x04: level 0 translation fault
> [   20.272764] Data abort info:
> [   20.275646]   ISV = 0, ISS = 0x00000044
> [   20.279494]   CM = 0, WnR = 1
> [   20.282469] [0042a2203dc65260] address between user and kernel address ranges
> [   20.289632] Internal error: Oops: 96000044 [#1] SMP
> [   20.294525] Modules linked in:
> [   20.297586] CPU: 1 PID: 1546 Comm: init Not tainted 5.15.0-next-20211109+ #1307
> [   20.304919] Hardware name: Kontron KBox A-230-LS (DT)
> [   20.309983] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [   20.316968] pc : queued_spin_lock_slowpath+0x1a8/0x3a0
> [   20.322127] lr : __mutex_unlock_slowpath.constprop.0+0x180/0x190
> [   20.328156] sp : ffff800013c23b80
> [   20.331475] x29: ffff800013c23b80 x28: ffff002003941040 x27: 0000000000000000
> [   20.338639] x26: ffff002000e49c90 x25: ffff80001167de48 x24: ffff800011f55578
> [   20.345802] x23: ffff002002b1d350 x22: 0000000000000002 x21: 0000000000000001
> [   20.352964] x20: ffff800013c23bb8 x19: ffff002002b1d350 x18: 00000000fffffffb
> [   20.360126] x17: 0000000000000001 x16: 0000000000000001 x15: 0000000000000020
> [   20.367288] x14: 0000000000000001 x13: 0000000000000000 x12: ffff002002c27938
> [   20.374450] x11: ffff002002c27908 x10: 0000000000000000 x9 : 0000000000080000
> [   20.381612] x8 : 0000000000000000 x7 : ffff00207f7b7a00 x6 : ffff8000119d1a00
> [   20.388774] x5 : ffff00207f7b7a00 x4 : 504322202c293830 x3 : ffff002002b1d358
> [   20.395936] x2 : ffff8000119d1a30 x1 : ffff8000119d1a30 x0 : ffff00207f7b7a08
> [   20.403098] Call trace:
> [   20.405546]  queued_spin_lock_slowpath+0x1a8/0x3a0
> [   20.410352]  mutex_unlock+0x5c/0x70
> [   20.413849]  spi_unregister_controller+0xf0/0x170
> [   20.418568]  dspi_remove+0x28/0xb0
> [   20.421978]  dspi_shutdown+0x1c/0x30
> [   20.425561]  platform_shutdown+0x30/0x40
> [   20.429495]  device_shutdown+0x14c/0x420
> [   20.433427]  __do_sys_reboot+0x214/0x29c
> [   20.437361]  __arm64_sys_reboot+0x30/0x40
> [   20.441380]  invoke_syscall+0x50/0x120
> [   20.445140]  el0_svc_common.constprop.0+0x58/0x190
> [   20.449944]  do_el0_svc+0x30/0x94
> [   20.453267]  el0_svc+0x20/0x90
> [   20.456327]  el0t_64_sync_handler+0x1a4/0x1b0
> [   20.460694]  el0t_64_sync+0x1a0/0x1a4
> [   20.464368] Code: 910020e0 8b0200c2 f861d884 aa0203e1 (f8246827)
> [   20.470479] ---[ end trace 9ee0c21f9e4bc5d5 ]---
> [   21.475251] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
> [   21.482940] Kernel Offset: disabled
> [   21.486433] CPU features: 0x2,000001c2,40000846
> [   21.490976] Memory Limit: none
> [   21.494036] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000 ]---
>
>  drivers/spi/spi.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index b23e675953e1..fdd530b150a7 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -3099,12 +3099,6 @@ void spi_unregister_controller(struct spi_controller *ctlr)
>
>         device_del(&ctlr->dev);
>
> -       /* Release the last reference on the controller if its driver
> -        * has not yet been converted to devm_spi_alloc_master/slave().
> -        */
> -       if (!ctlr->devm_allocated)
> -               put_device(&ctlr->dev);
> -
>         /* free bus id */
>         mutex_lock(&board_lock);
>         if (found == ctlr)
> @@ -3113,6 +3107,12 @@ void spi_unregister_controller(struct spi_controller *ctlr)
>
>         if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
>                 mutex_unlock(&ctlr->add_lock);
> +
> +       /* Release the last reference on the controller if its driver
> +        * has not yet been converted to devm_spi_alloc_master/slave().
> +        */
> +       if (!ctlr->devm_allocated)
> +               put_device(&ctlr->dev);
>  }
>  EXPORT_SYMBOL_GPL(spi_unregister_controller);
>
> --
> 2.30.2
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH] spi: fix use-after-free of the add_lock mutex
  2021-11-10 16:08 [RFC PATCH] spi: fix use-after-free of the add_lock mutex Michael Walle
  2021-11-10 16:27 ` Mark Brown
  2021-11-10 16:49 ` Andy Shevchenko
@ 2021-11-10 17:28 ` Uwe Kleine-König
  2021-11-11  5:19 ` Lukas Wunner
  3 siblings, 0 replies; 7+ messages in thread
From: Uwe Kleine-König @ 2021-11-10 17:28 UTC (permalink / raw)
  To: Michael Walle; +Cc: linux-spi, linux-kernel, Mark Brown, Vladimir Oltean

[-- Attachment #1: Type: text/plain, Size: 1399 bytes --]

Hello,

On Wed, Nov 10, 2021 at 05:08:36PM +0100, Michael Walle wrote:
> Commit 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on
> SPI buses") introduced a per-controller mutex. But mutex_unlock() of
> said lock is called after the controller is already freed:
> 
>   spi_unregister_controller(ctlr)
>    -> put_device(&ctlr->dev)
>     -> spi_controller_release(dev)
>   mutex_unlock(&ctrl->add_lock)

This is indented in a misleading way. mutex_unlock() has to be on the
same level as put_device().

> Move the put_device() after the mutex_unlock().
> 
> Fixes: 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on SPI buses")
> Signed-off-by: Michael Walle <michael@walle.cc>

I first thought this was wrong, and the put_device must be dropped
altogether, but after some code reading I agree this is the right fix.

Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

> ---
> I'm not sure if this is the correct fix. I don't know if the put_device()
> will have to be protected by the add_lock (remember before, the add_lock
> was a global lock).

No, put_device doesn't need to be protected by this lock.

Best regards and thanks for the report and diagnosis,
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH] spi: fix use-after-free of the add_lock mutex
  2021-11-10 16:08 [RFC PATCH] spi: fix use-after-free of the add_lock mutex Michael Walle
                   ` (2 preceding siblings ...)
  2021-11-10 17:28 ` Uwe Kleine-König
@ 2021-11-11  5:19 ` Lukas Wunner
  3 siblings, 0 replies; 7+ messages in thread
From: Lukas Wunner @ 2021-11-11  5:19 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-spi, linux-kernel, Mark Brown, Uwe Kleine-König,
	Vladimir Oltean, Andy Shevchenko

On Wed, Nov 10, 2021 at 05:08:36PM +0100, Michael Walle wrote:
> Commit 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on
> SPI buses") introduced a per-controller mutex. But mutex_unlock() of
> said lock is called after the controller is already freed:
> 
>   spi_unregister_controller(ctlr)
>    -> put_device(&ctlr->dev)
>     -> spi_controller_release(dev)
>   mutex_unlock(&ctrl->add_lock)
> 
> Move the put_device() after the mutex_unlock().
> 
> Fixes: 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on SPI buses")
> Signed-off-by: Michael Walle <michael@walle.cc>

Reviewed-by: Lukas Wunner <lukas@wunner.de>
Cc: stable@vger.kernel.org # v5.15

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-11-11  5:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-10 16:08 [RFC PATCH] spi: fix use-after-free of the add_lock mutex Michael Walle
2021-11-10 16:27 ` Mark Brown
2021-11-10 16:30   ` Michael Walle
2021-11-10 16:39     ` Mark Brown
2021-11-10 16:49 ` Andy Shevchenko
2021-11-10 17:28 ` Uwe Kleine-König
2021-11-11  5:19 ` Lukas Wunner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).