spi: controller registration fixes
Subsystems (2)
cover spi: controller registration fixes
This series fixes a few issues related to controller registration found through inspection.
Johan
Johan Hovold (5):
spi: fix use-after-free on controller registration failure
spi: fix statistics allocation
spi: drop unused devres statistics allocation
spi: fix misleading controller registration kernel-doc
spi: fix misleading controller deregistration kernel-doc
drivers/spi/spi.c | 60 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 31 deletions(-)
Signature · 1 line
2.52.0
PATCH 1/5 spi: fix use-after-free on controller registration failure
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.
--- drivers/spi/spi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/spi/spi.c +4 -4
@@ -3480,10 +3480,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);
@@ -3506,6 +3504,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_controller_idr, ctlr->bus_num);
Signature · 1 line
2.52.0
PATCH 2/5 spi: fix statistics allocation
In reply to Johan HovoldThe controller per-cpu statistics is not allocated until after the controller has been registered with driver core, which leaves a window where accessing the sysfs attributes can trigger a NULL-pointer dereference.
Fix this by moving the statistics allocation to controller allocation while tying its lifetime to that of the controller (rather than using implicit devres).
--- drivers/spi/spi.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/spi/spi.c +8 -9
@@ -3049,6 +3049,8 @@ static void spi_controller_release(struct device *dev)struct spi_controller *ctlr; ctlr = container_of(dev, struct spi_controller, dev); + +free_percpu (ctlr->pcpu_statistics);kfree (ctlr); }
@@ -3192,6 +3194,12 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,if (!ctlr)return NULL ; + ctlr->pcpu_statistics =spi_alloc_pcpu_stats (NULL ); +if (!ctlr->pcpu_statistics) { +kfree (ctlr); +return NULL ; + } +device_initialize (&ctlr->dev);INIT_LIST_HEAD (&ctlr->queue);spin_lock_init (&ctlr->queue_lock);
@@ -3483,13 +3491,6 @@ int spi_register_controller(struct spi_controller *ctlr)if (status) goto del_ctrl; } -/* Add statistics */ - ctlr->pcpu_statistics =spi_alloc_pcpu_stats (dev); -if (!ctlr->pcpu_statistics) { -dev_err (dev,"Error allocating per-cpu statistics\n" ); - status = -ENOMEM ; - goto destroy_queue; - }mutex_lock (&board_lock);list_add_tail (&ctlr->list, &spi_controller_list);
@@ -3502,8 +3503,6 @@ int spi_register_controller(struct spi_controller *ctlr)acpi_register_spi_devices (ctlr);return status; -destroy_queue: -spi_destroy_queue (ctlr); del_ctrl:device_del (&ctlr->dev); free_bus_id:
Signature · 1 line
2.52.0
PATCH 3/5 spi: drop unused devres statistics allocation
In reply to Johan HovoldDrop the now unused device managed per-cpu statistics allocation.
--- drivers/spi/spi.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-)
drivers/spi/spi.c +12 -15
@@ -96,25 +96,22 @@ static ssize_t driver_override_show(struct device *dev, }static DEVICE_ATTR_RW (driver_override); -static struct spi_statistics __percpu *spi_alloc_pcpu_stats (struct device *dev) +static struct spi_statistics __percpu *spi_alloc_pcpu_stats (void ) {struct spi_statistics __percpu *pcpu_stats; +int cpu; -if (dev) - pcpu_stats = devm_alloc_percpu(dev, struct spi_statistics); -else - pcpu_stats = alloc_percpu_gfp(struct spi_statistics, GFP_KERNEL); - -if (pcpu_stats) { -int cpu; + pcpu_stats = alloc_percpu_gfp(struct spi_statistics, GFP_KERNEL); +if (!pcpu_stats) +return NULL ; -for_each_possible_cpu (cpu) { -struct spi_statistics *stat; +for_each_possible_cpu (cpu) { +struct spi_statistics *stat; - stat =per_cpu_ptr (pcpu_stats, cpu); -u64_stats_init (&stat->syncp); - } + stat =per_cpu_ptr (pcpu_stats, cpu); +u64_stats_init (&stat->syncp); } +return pcpu_stats; }
@@ -574,7 +571,7 @@ struct spi_device *spi_alloc_device(struct spi_controller *ctlr)return NULL ; } - spi->pcpu_statistics =spi_alloc_pcpu_stats (NULL ); + spi->pcpu_statistics =spi_alloc_pcpu_stats ();if (!spi->pcpu_statistics) {kfree (spi);spi_controller_put (ctlr);
@@ -3194,7 +3191,7 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,if (!ctlr)return NULL ; - ctlr->pcpu_statistics =spi_alloc_pcpu_stats (NULL ); + ctlr->pcpu_statistics =spi_alloc_pcpu_stats ();if (!ctlr->pcpu_statistics) {kfree (ctlr);return NULL ;
Signature · 1 line
2.52.0
PATCH 4/5 spi: fix misleading controller registration kernel-doc
In reply to Johan HovoldThe controller reference count is not decremented on registration failures (and has not been for a very long time) contrary to what the outdated kernel-doc says.
Drop the entire sentence about return values which are now documented in the Return section.
--- drivers/spi/spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/spi.c +2 -2
@@ -3388,8 +3388,8 @@ static int spi_controller_id_alloc(struct spi_controller *ctlr, int start, int e* device identification, boards need configuration tables telling which * chip is at which address. * -* This must be called from context that can sleep. It returns zero on -* success, else a negative error code (dropping the controller's refcount). +* This must be called from context that can sleep. +* * After a successful return, the caller is responsible for calling * spi_unregister_controller(). *
Signature · 1 line
2.52.0
PATCH 5/5 spi: fix misleading controller deregistration kernel-doc
In reply to Johan HovoldThe controller reference count is not decremented on deregistration if the controller has been allocated using devm_spi_alloc_host/target().
Amend the kernel-doc for devm_spi_register_controller() and spi_unregister_controller() so that it reflects this (more recent) behaviour.
--- drivers/spi/spi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/spi/spi.c +4 -2
@@ -3523,7 +3523,8 @@ static void devm_spi_unregister_controller(void *ctlr)* Context: can sleep * * Register a SPI device as with spi_register_controller() which will -* automatically be unregistered and freed. +* automatically be unregistered (and freed unless it has been allocated using +* devm_spi_alloc_host/target()). * * Return: zero on success, else a negative error code. */
@@ -3557,7 +3558,8 @@ static int __unregister(struct device *dev, void *null)* * This must be called from context that can sleep. * -* Note that this function also drops a reference to the controller. +* Note that this function also drops a reference to the controller unless it +* has been allocated using devm_spi_alloc_host/target(). */ void spi_unregister_controller (struct spi_controller *ctlr) {
Signature · 1 line
2.52.0
Mark Brown
maintainerQuoted 8 lines · Johan Hovold
spi: controller registration fixes
This series fixes a few issues related to controller registration found through inspection.
Johan
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-7.1
Thanks!
[1/5] spi: fix use-after-free on controller registration failure
https://git.kernel.org/broonie/spi/c/8634e05b08ea [2/5] spi: fix statistics allocation https://git.kernel.org/broonie/spi/c/dee0774bbb2a [3/5] spi: drop unused devres statistics allocation https://git.kernel.org/broonie/spi/c/d5b4cb41b9a2 [4/5] spi: fix misleading controller registration kernel-doc https://git.kernel.org/broonie/spi/c/edc463d72d69 [5/5] spi: fix misleading controller deregistration kernel-doc https://git.kernel.org/broonie/spi/c/3f174274d224
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Mark Brown
maintainerQuoted 6 lines · Johan Hovold
This series fixes a few issues related to controller registration found through inspection.
Johan
Quoted 8 lines
Johan Hovold (5):
spi: fix use-after-free on controller registration failure
spi: fix statistics allocation
spi: drop unused devres statistics allocation
spi: fix misleading controller registration kernel-doc
spi: fix misleading controller deregistration kernel-doc[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
Thanks!
[1/5] spi: fix use-after-free on controller registration failure
https://git.kernel.org/broonie/misc/c/8634e05b08ea [2/5] spi: fix statistics allocation https://git.kernel.org/broonie/misc/c/dee0774bbb2a [3/5] spi: drop unused devres statistics allocation https://git.kernel.org/broonie/misc/c/d5b4cb41b9a2 [4/5] spi: fix misleading controller registration kernel-doc https://git.kernel.org/broonie/misc/c/edc463d72d69 [5/5] spi: fix misleading controller deregistration kernel-doc https://git.kernel.org/broonie/misc/c/3f174274d224
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark