Patch "spi: Prevent adding devices below an unregistering controller" has been added to the 4.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    spi: Prevent adding devices below an unregistering controller

to the 4.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     spi-prevent-adding-devices-below-an-unregistering-controller.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.


>From foo@baz Mon Dec 14 04:45:32 PM CET 2020
From: Lukas Wunner <lukas@xxxxxxxxx>
Date: Mon, 3 Aug 2020 13:09:01 +0200
Subject: spi: Prevent adding devices below an unregistering controller

From: Lukas Wunner <lukas@xxxxxxxxx>

commit ddf75be47ca748f8b12d28ac64d624354fddf189 upstream

CONFIG_OF_DYNAMIC and CONFIG_ACPI allow adding SPI devices at runtime
using a DeviceTree overlay or DSDT patch.  CONFIG_SPI_SLAVE allows the
same via sysfs.

But there are no precautions to prevent adding a device below a
controller that's being removed.  Such a device is unusable and may not
even be able to unbind cleanly as it becomes inaccessible once the
controller has been torn down.  E.g. it is then impossible to quiesce
the device's interrupt.

of_spi_notify() and acpi_spi_notify() do hold a ref on the controller,
but otherwise run lockless against spi_unregister_controller().

Fix by holding the spi_add_lock in spi_unregister_controller() and
bailing out of spi_add_device() if the controller has been unregistered
concurrently.

Fixes: ce79d54ae447 ("spi/of: Add OF notifier handler")
Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx # v3.19+
Cc: Geert Uytterhoeven <geert+renesas@xxxxxxxxx>
Cc: Octavian Purdila <octavian.purdila@xxxxxxxxx>
Cc: Pantelis Antoniou <pantelis.antoniou@xxxxxxxxxxxx>
Link: https://lore.kernel.org/r/a8c3205088a969dc8410eec1eba9aface60f36af.1596451035.git.lukas@xxxxxxxxx
Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
[sudip: adjust context]
Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@xxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/spi/Kconfig |    3 +++
 drivers/spi/spi.c   |   21 ++++++++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -706,4 +706,7 @@ endif # SPI_MASTER
 
 # (slave support would go here)
 
+config SPI_DYNAMIC
+	def_bool ACPI || OF_DYNAMIC || SPI_SLAVE
+
 endif # SPI
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -418,6 +418,12 @@ static LIST_HEAD(spi_master_list);
  */
 static DEFINE_MUTEX(board_lock);
 
+/*
+ * Prevents addition of devices with same chip select and
+ * addition of devices below an unregistering controller.
+ */
+static DEFINE_MUTEX(spi_add_lock);
+
 /**
  * spi_alloc_device - Allocate a new SPI device
  * @master: Controller to which device is connected
@@ -496,7 +502,6 @@ static int spi_dev_check(struct device *
  */
 int spi_add_device(struct spi_device *spi)
 {
-	static DEFINE_MUTEX(spi_add_lock);
 	struct spi_master *master = spi->master;
 	struct device *dev = master->dev.parent;
 	int status;
@@ -525,6 +530,13 @@ int spi_add_device(struct spi_device *sp
 		goto done;
 	}
 
+	/* Controller may unregister concurrently */
+	if (IS_ENABLED(CONFIG_SPI_DYNAMIC) &&
+	    !device_is_registered(&master->dev)) {
+		status = -ENODEV;
+		goto done;
+	}
+
 	if (master->cs_gpios)
 		spi->cs_gpio = master->cs_gpios[spi->chip_select];
 
@@ -1962,6 +1974,10 @@ static int __unregister(struct device *d
  */
 void spi_unregister_master(struct spi_master *master)
 {
+	/* Prevent addition of new devices, unregister existing ones */
+	if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
+		mutex_lock(&spi_add_lock);
+
 	device_for_each_child(&master->dev, NULL, __unregister);
 
 	if (master->queued) {
@@ -1981,6 +1997,9 @@ void spi_unregister_master(struct spi_ma
 	if (!devres_find(master->dev.parent, devm_spi_release_master,
 			 devm_spi_match_master, master))
 		put_device(&master->dev);
+
+	if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
+		mutex_unlock(&spi_add_lock);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_master);
 


Patches currently in stable-queue which might be from lukas@xxxxxxxxx are

queue-4.4/spi-bcm2835aux-fix-use-after-free-on-unbind.patch
queue-4.4/spi-bcm2835aux-restore-err-assignment-in-bcm2835aux_spi_probe.patch
queue-4.4/spi-prevent-adding-devices-below-an-unregistering-controller.patch



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux