From 565bdf45125a05aa8f622f58f598283f46ba43f4 Mon Sep 17 00:00:00 2001 From: Felix Gu Date: Fri, 17 Apr 2026 00:27:54 +0800 Subject: [PATCH 1/2] spi: atcspi200: fix use-after-free when driver unbind DMA resource is initialized after SPI controller registration. So when driver unbind, this can trigger a use-after-free when DMA is torn down while the controller is still alive and triggers DMA transfers. Fixes: 34e3815ea459 ("spi: atcspi200: Add ATCSPI200 SPI controller driver") Signed-off-by: Felix Gu Link: https://patch.msgid.link/20260417-atcspi-v1-1-854831667d63@gmail.com Signed-off-by: Mark Brown --- drivers/spi/spi-atcspi200.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-atcspi200.c b/drivers/spi/spi-atcspi200.c index 3832d9db3cbf..c5cf1aa2d674 100644 --- a/drivers/spi/spi-atcspi200.c +++ b/drivers/spi/spi-atcspi200.c @@ -575,12 +575,6 @@ static int atcspi_probe(struct platform_device *pdev) if (ret) goto free_controller; - ret = devm_spi_register_controller(&pdev->dev, host); - if (ret) { - dev_err_probe(spi->dev, ret, - "Failed to register SPI controller\n"); - goto free_controller; - } spi->use_dma = false; if (ATCSPI_DMA_SUPPORT) { ret = atcspi_configure_dma(spi); @@ -591,6 +585,13 @@ static int atcspi_probe(struct platform_device *pdev) spi->use_dma = true; } + ret = devm_spi_register_controller(&pdev->dev, host); + if (ret) { + dev_err_probe(spi->dev, ret, + "Failed to register SPI controller\n"); + goto free_controller; + } + return 0; free_controller: From aaea50c3bd768d03ee791b7428ac9b264777b6d7 Mon Sep 17 00:00:00 2001 From: Felix Gu Date: Fri, 17 Apr 2026 00:27:55 +0800 Subject: [PATCH 2/2] spi: atcspi200: switch to devm functions Switch to use devm_spi_alloc_host and devm_mutex_init to make code clean. Signed-off-by: Felix Gu Link: https://patch.msgid.link/20260417-atcspi-v1-2-854831667d63@gmail.com Signed-off-by: Mark Brown --- drivers/spi/spi-atcspi200.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/spi/spi-atcspi200.c b/drivers/spi/spi-atcspi200.c index c5cf1aa2d674..6d4b6aeb3f5b 100644 --- a/drivers/spi/spi-atcspi200.c +++ b/drivers/spi/spi-atcspi200.c @@ -550,7 +550,7 @@ static int atcspi_probe(struct platform_device *pdev) struct resource *mem_res; int ret; - host = spi_alloc_host(&pdev->dev, sizeof(*spi)); + host = devm_spi_alloc_host(&pdev->dev, sizeof(*spi)); if (!host) return -ENOMEM; @@ -559,21 +559,23 @@ static int atcspi_probe(struct platform_device *pdev) spi->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, host); - mutex_init(&spi->mutex_lock); + ret = devm_mutex_init(&pdev->dev, &spi->mutex_lock); + if (ret) + return ret; ret = atcspi_init_resources(pdev, spi, &mem_res); if (ret) - goto free_controller; + return ret; ret = atcspi_enable_clk(spi); if (ret) - goto free_controller; + return ret; atcspi_init_controller(pdev, spi, host, mem_res); ret = atcspi_setup(spi); if (ret) - goto free_controller; + return ret; spi->use_dma = false; if (ATCSPI_DMA_SUPPORT) { @@ -586,18 +588,11 @@ static int atcspi_probe(struct platform_device *pdev) } ret = devm_spi_register_controller(&pdev->dev, host); - if (ret) { - dev_err_probe(spi->dev, ret, - "Failed to register SPI controller\n"); - goto free_controller; - } + if (ret) + return dev_err_probe(spi->dev, ret, + "Failed to register SPI controller\n"); return 0; - -free_controller: - mutex_destroy(&spi->mutex_lock); - spi_controller_put(host); - return ret; } static int atcspi_suspend(struct device *dev)