spi: fix use-after-free of the add_lock mutex
authorMichael Walle <michael@walle.cc>
Thu, 11 Nov 2021 08:37:13 +0000 (09:37 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 12 Nov 2021 18:18:03 +0000 (18:18 +0000)
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: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Cc: stable@vger.kernel.org # v5.15
Link: https://lore.kernel.org/r/20211111083713.3335171-1-michael@walle.cc
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi.c

index 72826bd..a2988ae 100644 (file)
@@ -3058,12 +3058,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)
@@ -3072,6 +3066,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);