Skip to content

Commit

Permalink
mtd: spi-nor: core: Fix an issue of releasing resources during read/w…
Browse files Browse the repository at this point in the history
…rite

commit be94215 upstream.

If rmmod the driver during read or write, the driver will release the
resources which are used during read or write, so it is possible to
refer to NULL pointer.

Use the testcase "mtd_debug read /dev/mtd0 0xc00000 0x400000 dest_file &
sleep 0.5;rmmod spi_hisi_sfc_v3xx.ko", the issue can be reproduced in
hisi_sfc_v3xx driver.

To avoid the issue, fill the interface _get_device and _put_device of
mtd_info to grab the reference to the spi controller driver module, so
the request of rmmod the driver is rejected before read/write is finished.

Fixes: b199489 ("mtd: spi-nor: add the framework for SPI NOR")
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Tested-by: Michael Walle <michael@walle.cc>
Tested-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Michael Walle <michael@walle.cc>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/1617262486-4223-1-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Xiang Chen authored and gregkh committed May 11, 2021
1 parent 4c44c13 commit 2e41cc1
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions drivers/mtd/spi-nor/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2981,6 +2981,37 @@ static void spi_nor_resume(struct mtd_info *mtd)
dev_err(dev, "resume() failed\n");
}

static int spi_nor_get_device(struct mtd_info *mtd)
{
struct mtd_info *master = mtd_get_master(mtd);
struct spi_nor *nor = mtd_to_spi_nor(master);
struct device *dev;

if (nor->spimem)
dev = nor->spimem->spi->controller->dev.parent;
else
dev = nor->dev;

if (!try_module_get(dev->driver->owner))
return -ENODEV;

return 0;
}

static void spi_nor_put_device(struct mtd_info *mtd)
{
struct mtd_info *master = mtd_get_master(mtd);
struct spi_nor *nor = mtd_to_spi_nor(master);
struct device *dev;

if (nor->spimem)
dev = nor->spimem->spi->controller->dev.parent;
else
dev = nor->dev;

module_put(dev->driver->owner);
}

void spi_nor_restore(struct spi_nor *nor)
{
/* restore the addressing mode */
Expand Down Expand Up @@ -3157,6 +3188,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
mtd->_erase = spi_nor_erase;
mtd->_read = spi_nor_read;
mtd->_resume = spi_nor_resume;
mtd->_get_device = spi_nor_get_device;
mtd->_put_device = spi_nor_put_device;

if (nor->params->locking_ops) {
mtd->_lock = spi_nor_lock;
Expand Down

0 comments on commit 2e41cc1

Please sign in to comment.