2022-01-06 13:23:07

by Patrice CHOTARD

[permalink] [raw]
Subject: spi: stm32-qspi: Update spi registering

From: Patrice Chotard <[email protected]>

Replace devm_spi_register_master() by spi_register_master() to ensure
that spi sub-nodes are unregistered in the correct order when qspi driver
is removed.
This issue was put in evidence using kernel v5.11 and later
with a spi-nor which supports the software reset feature introduced
by commit d73ee7534cc5 ("mtd: spi-nor: core: perform a Soft Reset on shutdown")

Signed-off-by: Patrice Chotard <[email protected]>
---
drivers/spi/spi-stm32-qspi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index 514337c86d2c..db005443aa7c 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -784,7 +784,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
pm_runtime_get_noresume(dev);

- ret = devm_spi_register_master(dev, ctrl);
+ ret = spi_register_master(ctrl);
if (ret)
goto err_pm_runtime_free;

@@ -817,6 +817,7 @@ static int stm32_qspi_remove(struct platform_device *pdev)
struct stm32_qspi *qspi = platform_get_drvdata(pdev);

pm_runtime_get_sync(qspi->dev);
+ spi_unregister_master(qspi->ctrl);
/* disable qspi */
writel_relaxed(0, qspi->io_base + QSPI_CR);
stm32_qspi_dma_free(qspi);
--
2.17.1



2022-01-06 13:51:28

by Mark Brown

[permalink] [raw]
Subject: Re: spi: stm32-qspi: Update spi registering

On Thu, Jan 06, 2022 at 02:20:52PM +0100, [email protected] wrote:
> From: Patrice Chotard <[email protected]>
>
> Replace devm_spi_register_master() by spi_register_master() to ensure
> that spi sub-nodes are unregistered in the correct order when qspi driver
> is removed.

This commit message doesn't describe the actual issue. The change is
fixing ordering within the driver itself - the driver is freeing things
in the remove() callback which are used by the controller but thanks to
the use of devm the controller isn't unregistered from the core until
after the remove() callback has run so we might still have something
running. "Subnodes" aren't an issue here.

Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.


Attachments:
(No filename) (1.00 kB)
signature.asc (488.00 B)
Download all attachments

2022-01-08 19:48:24

by Lukas Wunner

[permalink] [raw]
Subject: Re: spi: stm32-qspi: Update spi registering

On Thu, Jan 06, 2022 at 02:20:52PM +0100, [email protected] wrote:
> --- a/drivers/spi/spi-stm32-qspi.c
> +++ b/drivers/spi/spi-stm32-qspi.c
> @@ -784,7 +784,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
> pm_runtime_enable(dev);
> pm_runtime_get_noresume(dev);
>
> - ret = devm_spi_register_master(dev, ctrl);
> + ret = spi_register_master(ctrl);
> if (ret)
> goto err_pm_runtime_free;
>
> @@ -817,6 +817,7 @@ static int stm32_qspi_remove(struct platform_device *pdev)
> struct stm32_qspi *qspi = platform_get_drvdata(pdev);
>
> pm_runtime_get_sync(qspi->dev);
> + spi_unregister_master(qspi->ctrl);
> /* disable qspi */
> writel_relaxed(0, qspi->io_base + QSPI_CR);
> stm32_qspi_dma_free(qspi);

NAK, this introduces a use-after-free because the "qspi" allocation
is freed by spi_unregister_master(), yet is subsequently accessed.

You need to convert the driver to devm_spi_alloc_master() to avoid that.
Do it in the same patch to ease backporting.

Please add a stable designation and a Fixes: tag. Chances are the patch
needs to be backported all the way back to the release when the driver
was first introduced.

Thanks,

Lukas

2022-01-12 13:18:23

by Patrice CHOTARD

[permalink] [raw]
Subject: Re: spi: stm32-qspi: Update spi registering

Hi Mark

On 1/6/22 2:51 PM, Mark Brown wrote:
> On Thu, Jan 06, 2022 at 02:20:52PM +0100, [email protected] wrote:
>> From: Patrice Chotard <[email protected]>
>>
>> Replace devm_spi_register_master() by spi_register_master() to ensure
>> that spi sub-nodes are unregistered in the correct order when qspi driver
>> is removed.
>
> This commit message doesn't describe the actual issue. The change is
> fixing ordering within the driver itself - the driver is freeing things
> in the remove() callback which are used by the controller but thanks to
> the use of devm the controller isn't unregistered from the core until
> after the remove() callback has run so we might still have something
> running. "Subnodes" aren't an issue here.

OK i will update this comment to be clearer.

>
> Please submit patches using subject lines reflecting the style for the
> subsystem, this makes it easier for people to identify relevant patches.
> Look at what existing commits in the area you're changing are doing and
> make sure your subject lines visually resemble what they're doing.
> There's no need to resubmit to fix this alone.
>

Agree, i forgot to use the correct script to submit patches to ML.

Thanks
Patrice

2022-01-12 13:54:26

by Patrice CHOTARD

[permalink] [raw]
Subject: Re: spi: stm32-qspi: Update spi registering

Hi Lukas

On 1/8/22 8:48 PM, Lukas Wunner wrote:
> On Thu, Jan 06, 2022 at 02:20:52PM +0100, [email protected] wrote:
>> --- a/drivers/spi/spi-stm32-qspi.c
>> +++ b/drivers/spi/spi-stm32-qspi.c
>> @@ -784,7 +784,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
>> pm_runtime_enable(dev);
>> pm_runtime_get_noresume(dev);
>>
>> - ret = devm_spi_register_master(dev, ctrl);
>> + ret = spi_register_master(ctrl);
>> if (ret)
>> goto err_pm_runtime_free;
>>
>> @@ -817,6 +817,7 @@ static int stm32_qspi_remove(struct platform_device *pdev)
>> struct stm32_qspi *qspi = platform_get_drvdata(pdev);
>>
>> pm_runtime_get_sync(qspi->dev);
>> + spi_unregister_master(qspi->ctrl);
>> /* disable qspi */
>> writel_relaxed(0, qspi->io_base + QSPI_CR);
>> stm32_qspi_dma_free(qspi);
>
> NAK, this introduces a use-after-free because the "qspi" allocation
> is freed by spi_unregister_master(), yet is subsequently accessed.
>
> You need to convert the driver to devm_spi_alloc_master() to avoid that.
> Do it in the same patch to ease backporting.

Ok i see, spi_unregister_controller() is releasing the controller if it wasn't
previously devm allocated. I will make usage of devm_spi_alloc_master as you suggested.

>
> Please add a stable designation and a Fixes: tag. Chances are the patch
> needs to be backported all the way back to the release when the driver
> was first introduced.
>
> Thanks,
>
> Lukas
>
Thanks
Patrice