summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorDuoming Zhou <duoming@zju.edu.cn>2025-09-20 21:42:01 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-10-19 16:33:38 +0200
commit00d3af40b158ebf7c7db2b3bbb1598a54bf28127 (patch)
treefb68ea6f5a6a28620d241cfdd2094a27d45fd7a6 /drivers/scsi
parent5e1020047cb73dd35402917586c7b69ff5786bf7 (diff)
downloadlinux-00d3af40b158ebf7c7db2b3bbb1598a54bf28127.tar.gz
linux-00d3af40b158ebf7c7db2b3bbb1598a54bf28127.tar.bz2
linux-00d3af40b158ebf7c7db2b3bbb1598a54bf28127.zip
scsi: mvsas: Fix use-after-free bugs in mvs_work_queue
[ Upstream commit 60cd16a3b7439ccb699d0bf533799eeb894fd217 ] During the detaching of Marvell's SAS/SATA controller, the original code calls cancel_delayed_work() in mvs_free() to cancel the delayed work item mwq->work_q. However, if mwq->work_q is already running, the cancel_delayed_work() may fail to cancel it. This can lead to use-after-free scenarios where mvs_free() frees the mvs_info while mvs_work_queue() is still executing and attempts to access the already-freed mvs_info. A typical race condition is illustrated below: CPU 0 (remove) | CPU 1 (delayed work callback) mvs_pci_remove() | mvs_free() | mvs_work_queue() cancel_delayed_work() | kfree(mvi) | | mvi-> // UAF Replace cancel_delayed_work() with cancel_delayed_work_sync() to ensure that the delayed work item is properly canceled and any executing delayed work item completes before the mvs_info is deallocated. This bug was found by static analysis. Fixes: 20b09c2992fe ("[SCSI] mvsas: add support for 94xx; layout change; bug fixes") Signed-off-by: Duoming Zhou <duoming@zju.edu.cn> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/mvsas/mv_init.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 020037cbf0d9..655cca5fe7cc 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -124,7 +124,7 @@ static void mvs_free(struct mvs_info *mvi)
if (mvi->shost)
scsi_host_put(mvi->shost);
list_for_each_entry(mwq, &mvi->wq_list, entry)
- cancel_delayed_work(&mwq->work_q);
+ cancel_delayed_work_sync(&mwq->work_q);
kfree(mvi->rsvd_tags);
kfree(mvi);
}