[PATCH v1] mtd: rawnand: r852: Prevent card work during removal
From: Yibo Tan
Date: Tue Sep 15 2026 - 11:24:53 EST
r852_irq() queues card_detect_work when card state changes. r852_remove()
currently cancels that work and destroys its private workqueue before it
disables and frees the IRQ.
A card event in this interval can queue delayed work on the destroyed
workqueue. Its timer is part of struct r852_device, which is freed later
in r852_remove(). KASAN reported a use-after-free in the timer code when
the card interrupt occurred in this interval. The same test completed
without a kernel diagnostic after this change.
Set a removal flag while holding irqlock before cancelling the work. The
IRQ handler still acknowledges and disables card events, but does not
queue more card-detect work during removal. The lock ensures that work
queued before the flag is cancelled and later interrupts skip the queue.
Fixes: 67e054e91924 ("mtd: nand: Add driver for Ricoh xD/SmartMedia reader")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@xxxxxxxxxx>
---
drivers/mtd/nand/raw/r852.c | 7 +++++++
drivers/mtd/nand/raw/r852.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/drivers/mtd/nand/raw/r852.c b/drivers/mtd/nand/raw/r852.c
index 92c47d351c27..6170a481cb1f 100644
--- a/drivers/mtd/nand/raw/r852.c
+++ b/drivers/mtd/nand/raw/r852.c
@@ -747,6 +747,9 @@ static irqreturn_t r852_irq(int irq, void *data)
/* this will timeout DMA if active, but better that garbage */
r852_disable_irqs(dev);
+ if (dev->removing)
+ goto out;
+
if (dev->card_unstable)
goto out;
@@ -977,6 +980,10 @@ static void r852_remove(struct pci_dev *pci_dev)
{
struct r852_device *dev = pci_get_drvdata(pci_dev);
+ spin_lock_irq(&dev->irqlock);
+ dev->removing = true;
+ spin_unlock_irq(&dev->irqlock);
+
/* Stop detect workqueue -
we are going to unregister the device anyway*/
cancel_delayed_work_sync(&dev->card_detect_work);
diff --git a/drivers/mtd/nand/raw/r852.h b/drivers/mtd/nand/raw/r852.h
index 96fe301d15da..5c931880c2f4 100644
--- a/drivers/mtd/nand/raw/r852.h
+++ b/drivers/mtd/nand/raw/r852.h
@@ -131,6 +131,7 @@ struct r852_device {
int card_detected; /* card detected in slot */
int card_unstable; /* whenever the card is inserted,
is not known yet */
+ bool removing; /* do not queue card work during removal */
int readonly; /* card is readonly */
int sm; /* Is card smartmedia */
--
2.39.5