[PATCH] scsi: mvsas: fix tasklet use-after-free in mvs_pci_remove

Fan Wu <[email protected]>
Newsgroups org.kernel.vger.linux-scsi,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
The tasklet is killed before the device IRQ is freed. The IRQ handler
schedules the tasklet, so an interrupt after tasklet_kill() can
reschedule it to run after its backing data has been freed, and the
tasklet re-enables the interrupt on exit. Move tasklet_kill() below
free_irq() and disable the interrupt again once it has drained.

This issue was found by an in-house static analysis tool.

Fixes: 6f8ac161b8b3 ("[SCSI] mvsas: Add support for interrupt tasklet")
Cc: [email protected]
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <[email protected]>
---
 drivers/scsi/mvsas/mv_init.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -588,13 +588,14 @@ static void mvs_pci_remove(struct pci_dev *pdev)
 	core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
 	mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];

-#ifdef CONFIG_SCSI_MVSAS_TASKLET
-	tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
-#endif
-
 	sas_unregister_ha(sha);
 	sas_remove_host(mvi->shost);

 	MVS_CHIP_DISP->interrupt_disable(mvi);
 	free_irq(mvi->pdev->irq, sha);
+#ifdef CONFIG_SCSI_MVSAS_TASKLET
+	/* drain after free_irq(): the tasklet re-enables the IRQ on exit */
+	tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
+	MVS_CHIP_DISP->interrupt_disable(mvi);
+#endif
 	for (i = 0; i < core_nr; i++) {
 		mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[i];
 		mvs_free(mvi);
--
2.39.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.