From: sashiko-bot@kernel.org
To: "Fan Wu" <fanwu01@zju.edu.cn>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH] scsi: smartpqi: cancel pending workers before freeing controller
Date: Wed, 01 Jul 2026 14:53:12 +0000 [thread overview]
Message-ID: <20260701145313.31D6A1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260701142757.8447-1-fanwu01@zju.edu.cn>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] Canceling event_work during controller teardown introduces an unrecoverable deadlock if the worker is blocked in pqi_wait_if_ctrl_blocked().
Pre-existing issues:
- [Critical] Concurrent execution of `pqi_fail_all_outstanding_requests` can lead to double completion of SCSI commands, causing a use-after-free and double-free vulnerability.
- [High] Incomplete teardown ordering allows `event_work` to re-arm `rescan_work` after it has been cancelled, leading to a Use-After-Free when `ctrl_info` is freed.
- [High] `pqi_suspend_or_freeze()` races with `ctrl_offline_work`, causing a double free of IRQ vectors.
--
commit 038afb1987e7de8ef32f28b104faf6296b50e850
Author: Fan Wu <fanwu01@zju.edu.cn>
scsi: smartpqi: cancel pending workers before freeing controller
The smartpqi driver does not cancel pending workers during controller
teardown, leading to use-after-free bugs when queued workers dereference a
freed controller. This patch drains the workers in pqi_free_ctrl_resources()
using disable_work_sync() and cancel_work_sync() in an order that prevents
arming chains from surviving the teardown.
> diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
> index 5ec583dc2e7df..b16c50761f1ca 100644
> --- a/drivers/scsi/smartpqi/smartpqi_init.c
> +++ b/drivers/scsi/smartpqi/smartpqi_init.c
> @@ -8897,7 +8897,16 @@ static void pqi_free_interrupts(struct pqi_ctrl_info *ctrl_info)
>
> static void pqi_free_ctrl_resources(struct pqi_ctrl_info *ctrl_info)
> {
> + /*
> + * Disable, not cancel: the callback also frees IRQs, and
> + * pqi_take_ctrl_offline() can re-queue it after a cancel.
> + */
> + disable_work_sync(&ctrl_info->ctrl_offline_work);
[Severity: Critical]
This is a pre-existing issue, but can concurrent execution of
pqi_fail_all_outstanding_requests() lead to double completion of SCSI
commands?
pqi_fail_all_outstanding_requests() iterates over the I/O request pool and
completes requests using a non-atomic check:
smartpqi_init.c:pqi_fail_all_outstanding_requests() {
...
if (atomic_read(&io_request->refcount) == 0)
continue;
...
}
If a hardware error triggers ctrl_offline_work while a surprise removal
triggers pqi_remove_ctrl(), both threads can execute
pqi_fail_all_outstanding_requests() concurrently.
Both threads might see a non-zero refcount and invoke io_complete_callback
for the same request, leading to double frees and data corruption.
[Severity: High]
This is a pre-existing issue, but can pqi_suspend_or_freeze() race with
ctrl_offline_work and cause a double free of IRQ vectors?
pqi_suspend_or_freeze() calls pqi_free_irqs() without draining
ctrl_offline_work. If a hardware error queues ctrl_offline_work just before
suspend, the worker runs concurrently and also calls pqi_free_irqs().
Because pqi_free_irqs() lacks locking:
smartpqi_init.c:pqi_free_irqs() {
for (i = 0; i < ctrl_info->num_msix_vectors_initialized; i++)
free_irq(pci_irq_vector(ctrl_info->pci_dev, i),
&ctrl_info->queue_groups[i]);
...
}
Both threads can simultaneously read a positive num_msix_vectors_initialized
and call free_irq() on the same MSI-X vectors.
> pqi_free_interrupts(ctrl_info);
> + /* IRQs queue event_work, which can queue OFA work. */
> + cancel_work_sync(&ctrl_info->event_work);
[Severity: High]
Does this cancellation introduce a deadlock if the event worker is currently
blocked?
In pqi_remove_ctrl(), pqi_ctrl_block_requests() is called which sets
block_requests to true.
If event_work is executing, its callback pqi_event_worker() unconditionally
waits for block_requests to become false:
smartpqi_init.c:pqi_event_worker() {
...
pqi_wait_if_ctrl_blocked(ctrl_info);
...
}
Since block_requests is never cleared during teardown, the worker blocks
forever. cancel_work_sync() will then wait forever for the worker to finish,
causing a deadlock.
[Severity: High]
This is a pre-existing issue, but does the teardown order allow event_work
to re-arm rescan_work after it was cancelled?
In pqi_remove_ctrl(), pqi_cancel_rescan_worker() cancels rescan_work before
pqi_free_ctrl_resources() drains event_work here.
However, event_work can arm rescan_work via
pqi_schedule_rescan_worker_with_delay():
smartpqi_init.c:pqi_schedule_rescan_worker_with_delay() {
if (pqi_ctrl_offline(ctrl_info))
return;
schedule_delayed_work(&ctrl_info->rescan_work, delay);
}
If event_work checks pqi_ctrl_offline() and sees false, but is preempted
while pqi_remove_ctrl() sets the controller offline and cancels rescan_work,
the resumed event_work will queue rescan_work again.
This newly queued work is leaked and could cause a use-after-free when the
controller is freed.
> + cancel_work_sync(&ctrl_info->ofa_memory_alloc_work);
> + cancel_work_sync(&ctrl_info->ofa_quiesce_work);
> if (ctrl_info->queue_memory_base)
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260701142757.8447-1-fanwu01@zju.edu.cn?part=1
next prev parent reply other threads:[~2026-07-01 14:53 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 14:27 [PATCH] scsi: smartpqi: cancel pending workers before freeing controller Fan Wu
2026-07-01 14:53 ` sashiko-bot [this message]
2026-07-04 1:50 ` [PATCH v2] scsi: smartpqi: drain controller " Fan Wu
2026-07-04 2:18 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260701145313.31D6A1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=fanwu01@zju.edu.cn \
--cc=linux-scsi@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.