[PATCH 16/17] mpi3mr: Fix use-after-free of the firmware event workqueue
Chandrakanth Patil <[email protected]>
| Newsgroups | org.kernel.vger.linux-scsi |
|---|---|
| Message-ID | <[email protected]> |
The enqueue path reads the workqueue pointer before taking the event
lock, while the remove path clears that pointer and destroys the
workqueue while holding it. The enqueue can therefore reach
queue_work() after the workqueue is gone.
Move the check inside the lock.
Fixes: 13ef29ea4aa0 ("scsi: mpi3mr: Add support for device add/remove event handling")
Signed-off-by: Chandrakanth Patil <[email protected]>
---
drivers/scsi/mpi3mr/mpi3mr_os.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index 00bd654d7f24..c740a64164e5 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -233,10 +233,11 @@ static void mpi3mr_fwevt_add_to_list(struct mpi3mr_ioc *mrioc,
{
unsigned long flags;
- if (!mrioc->fwevt_worker_thread)
- return;
-
spin_lock_irqsave(&mrioc->fwevt_lock, flags);
+ if (!mrioc->fwevt_worker_thread) {
+ spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);
+ return;
+ }
/* get fwevt reference count while adding it to fwevt_list */
mpi3mr_fwevt_get(fwevt);
INIT_LIST_HEAD(&fwevt->list);