CVE-2024-26807
Théo Lebrun (1): spi: cadence-qspi: fix pointer reference in runtime PM hooks
Vaishnav Achath (2): spi: cadence-quadspi: Handle spi_unregister_master() in remove() spi: cadence-quadspi: Remove spi_master_put() in probe failure path
drivers/spi/spi-cadence-quadspi.c | 35 +++++++++++++------------------ 1 file changed, 14 insertions(+), 21 deletions(-)
From: Théo Lebrun theo.lebrun@bootlin.com
stable inclusion from stable-v6.6.21 commit 03f1573c9587029730ca68503f5062105b122f61 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9E475 CVE: CVE-2024-26807
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
dev_get_drvdata() gets used to acquire the pointer to cqspi and the SPI controller. Neither embed the other; this lead to memory corruption.
On a given platform (Mobileye EyeQ5) the memory corruption is hidden inside cqspi->f_pdata. Also, this uninitialised memory is used as a mutex (ctlr->bus_lock_mutex) by spi_controller_suspend().
Fixes: 2087e85bb66e ("spi: cadence-quadspi: fix suspend-resume implementations") Reviewed-by: Dhruva Gole d-gole@ti.com Signed-off-by: Théo Lebrun theo.lebrun@bootlin.com Link: https://msgid.link/r/20240222-cdns-qspi-pm-fix-v4-1-6b6af8bcbf59@bootlin.com Signed-off-by: Mark Brown broonie@kernel.org Conflicts: drivers/spi/spi-cadence-quadspi.c Signed-off-by: Liao Chen liaochen4@huawei.com --- drivers/spi/spi-cadence-quadspi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 23d50a19ae27..e275c05d0045 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1355,10 +1355,9 @@ static int cqspi_remove(struct platform_device *pdev) static int cqspi_suspend(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); - struct spi_master *master = dev_get_drvdata(dev); int ret;
- ret = spi_master_suspend(master); + ret = spi_master_suspend(cqspi->master); cqspi_controller_enable(cqspi, 0);
clk_disable_unprepare(cqspi->clk); @@ -1369,7 +1368,6 @@ static int cqspi_suspend(struct device *dev) static int cqspi_resume(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); - struct spi_master *master = dev_get_drvdata(dev);
clk_prepare_enable(cqspi->clk); cqspi_wait_idle(cqspi); @@ -1378,7 +1376,7 @@ static int cqspi_resume(struct device *dev) cqspi->current_cs = -1; cqspi->sclk = 0;
- return spi_master_resume(master); + return spi_master_resume(cqspi->master); }
static const struct dev_pm_ops cqspi__dev_pm_ops = {
From: Vaishnav Achath vaishnav.a@ti.com
mainline inclusion from mainline-v5.19-rc1 commit 606e5d408184989f53028125e0cb5aa6713362d5 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9E475 CVE: CVE-2024-26807
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Currently devres managed removal of the spi_controller happens after removing the power domain of the host platform_device.While this does not affect the clean removal of the controller, but affects graceful removal of the child devices if the child device removal requires issuing commands over SPI.
Eg. flash device being soft reset to 1S-1S-1S mode before removal so that on next probe operations in 1S-1S-1S mode is successful.
Failure is seen when `rmmod spi-cadence-quadspi` is performed:
root@j7-evm:~# rmmod spi_cadence_quadspi [ 49.230996] cadence-qspi 47050000.spi: QSPI is still busy after 500ms timeout. [ 49.238209] spi-nor spi1.0: operation failed with -110 [ 49.244457] spi-nor spi1.0: Software reset failed: -110
and on subsequent modprobe the OSPI flash probe fails as it is in 8D-8D-8D mode since the previous soft reset did not happen.
root@j7-evm:~# modprobe spi_cadence_quadspi [ 73.253536] spi-nor spi0.0: unrecognized JEDEC id bytes: ff ff ff ff ff ff [ 73.260476] spi-nor: probe of spi0.0 failed with error -2
This commit adds necessary changes to perform spi_unregister_master() in the host device remove() so that the child devices are gracefully removed before the power domain is removed.
changes tested on J721E with mt35xu512aba flash.
Signed-off-by: Vaishnav Achath vaishnav.a@ti.com Link: https://lore.kernel.org/r/20220511115516.14894-1-vaishnav.a@ti.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Liao Chen liaochen4@huawei.com --- drivers/spi/spi-cadence-quadspi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index e275c05d0045..392d20ead254 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -57,7 +57,7 @@ struct cqspi_flash_pdata {
struct cqspi_st { struct platform_device *pdev; - + struct spi_master *master; struct clk *clk; unsigned int sclk;
@@ -1186,7 +1186,7 @@ static int cqspi_probe(struct platform_device *pdev) int ret; int irq;
- master = spi_alloc_master(&pdev->dev, sizeof(*cqspi)); + master = devm_spi_alloc_master(&pdev->dev, sizeof(*cqspi)); if (!master) { dev_err(&pdev->dev, "spi_alloc_master failed\n"); return -ENOMEM; @@ -1198,6 +1198,7 @@ static int cqspi_probe(struct platform_device *pdev) cqspi = spi_master_get_devdata(master);
cqspi->pdev = pdev; + cqspi->master = master; platform_set_drvdata(pdev, cqspi);
/* Obtain configuration from OF. */ @@ -1315,7 +1316,7 @@ static int cqspi_probe(struct platform_device *pdev) goto probe_setup_failed; }
- ret = devm_spi_register_master(dev, master); + ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret); goto probe_setup_failed; @@ -1338,6 +1339,7 @@ static int cqspi_remove(struct platform_device *pdev) { struct cqspi_st *cqspi = platform_get_drvdata(pdev);
+ spi_unregister_master(cqspi->master); cqspi_controller_enable(cqspi, 0);
if (cqspi->rx_chan)
From: Vaishnav Achath vaishnav.a@ti.com
mainline inclusion from mainline-v5.19-rc7 commit 73d5fe046270281a46344e06bf986c607632f7ea category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9E475 CVE: CVE-2024-26807
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Currently the spi_master is allocated by devm_spi_alloc_master() and devres core manages the deallocation, but in probe failure path spi_master_put() is being handled manually which causes "refcount underflow use-after-free" warning when probe failure happens after allocating spi_master.
Trimmed backtrace during failure:
refcount_t: underflow; use-after-free. pc : refcount_warn_saturate+0xf4/0x144 Call trace: refcount_warn_saturate kobject_put put_device devm_spi_release_controller devres_release_all
This commit makes relevant changes to remove spi_master_put() from probe failure path.
Fixes: 606e5d408184 ("spi: cadence-quadspi: Handle spi_unregister_master() in remove()")
Signed-off-by: Vaishnav Achath vaishnav.a@ti.com Link: https://lore.kernel.org/r/20220601071611.11853-1-vaishnav.a@ti.com Signed-off-by: Mark Brown broonie@kernel.org Conflicts: drivers/spi/spi-cadence-quadspi.c Signed-off-by: Liao Chen liaochen4@huawei.com --- drivers/spi/spi-cadence-quadspi.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 392d20ead254..041e651eaebf 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1205,8 +1205,7 @@ static int cqspi_probe(struct platform_device *pdev) ret = cqspi_of_get_pdata(cqspi); if (ret) { dev_err(dev, "Cannot get mandatory OF data.\n"); - ret = -ENODEV; - goto probe_master_put; + return -ENODEV; }
/* Obtain QSPI clock. */ @@ -1214,7 +1213,7 @@ static int cqspi_probe(struct platform_device *pdev) if (IS_ERR(cqspi->clk)) { dev_err(dev, "Cannot claim QSPI clock.\n"); ret = PTR_ERR(cqspi->clk); - goto probe_master_put; + return ret; }
/* Obtain and remap controller address. */ @@ -1223,7 +1222,7 @@ static int cqspi_probe(struct platform_device *pdev) if (IS_ERR(cqspi->iobase)) { dev_err(dev, "Cannot remap controller address.\n"); ret = PTR_ERR(cqspi->iobase); - goto probe_master_put; + return ret; }
/* Obtain and remap AHB address. */ @@ -1232,7 +1231,7 @@ static int cqspi_probe(struct platform_device *pdev) if (IS_ERR(cqspi->ahb_base)) { dev_err(dev, "Cannot remap AHB address.\n"); ret = PTR_ERR(cqspi->ahb_base); - goto probe_master_put; + return ret; } cqspi->mmap_phys_base = (dma_addr_t)res_ahb->start; cqspi->ahb_size = resource_size(res_ahb); @@ -1241,17 +1240,13 @@ static int cqspi_probe(struct platform_device *pdev)
/* Obtain IRQ line. */ irq = platform_get_irq(pdev, 0); - if (irq < 0) { + if (irq < 0) ret = -ENXIO; - goto probe_master_put; - }
pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_noidle(dev); - goto probe_master_put; - } + if (ret < 0) + return ret;
ret = clk_prepare_enable(cqspi->clk); if (ret) { @@ -1330,8 +1325,6 @@ static int cqspi_probe(struct platform_device *pdev) probe_clk_failed: pm_runtime_put_sync(dev); pm_runtime_disable(dev); -probe_master_put: - spi_master_put(master); return ret; }
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/7222 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/H...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/7222 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/H...