summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2026-03-12 16:18:13 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-03-25 11:06:04 +0100
commit6bbd385b30c7fb6c7ee0669e9ada91490938c051 (patch)
tree7c504c277b0592b0dcce5a312bd485ca84fcbdbc /drivers/spi
parent9443202d91388026dbf7312972a74fbfd27ee82f (diff)
downloadlinux-6bbd385b30c7fb6c7ee0669e9ada91490938c051.tar.gz
linux-6bbd385b30c7fb6c7ee0669e9ada91490938c051.tar.bz2
linux-6bbd385b30c7fb6c7ee0669e9ada91490938c051.zip
spi: fix use-after-free on controller registration failure
commit 8634e05b08ead636e926022f4a98416e13440df9 upstream. Make sure to deregister from driver core also in the unlikely event that per-cpu statistics allocation fails during controller registration to avoid use-after-free (of driver resources) and unclocked register accesses. Fixes: 6598b91b5ac3 ("spi: spi.c: Convert statistics to per-cpu u64_stats_t") Cc: stable@vger.kernel.org # 6.0 Cc: David Jander <david@protonic.nl> Signed-off-by: Johan Hovold <johan@kernel.org> Link: https://patch.msgid.link/20260312151817.32100-2-johan@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 5adba36255a1..180fd72bce5d 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3213,10 +3213,8 @@ int spi_register_controller(struct spi_controller *ctlr)
dev_info(dev, "controller is unqueued, this is deprecated\n");
} else if (ctlr->transfer_one || ctlr->transfer_one_message) {
status = spi_controller_initialize_queue(ctlr);
- if (status) {
- device_del(&ctlr->dev);
- goto free_bus_id;
- }
+ if (status)
+ goto del_ctrl;
}
/* Add statistics */
ctlr->pcpu_statistics = spi_alloc_pcpu_stats(dev);
@@ -3239,6 +3237,8 @@ int spi_register_controller(struct spi_controller *ctlr)
destroy_queue:
spi_destroy_queue(ctlr);
+del_ctrl:
+ device_del(&ctlr->dev);
free_bus_id:
mutex_lock(&board_lock);
idr_remove(&spi_master_idr, ctlr->bus_num);