From: sashiko-bot@kernel.org
To: "Eric Farman" <farman@linux.ibm.com>
Cc: "Heiko Carstens" <hca@linux.ibm.com>,
"Alexander Gordeev" <agordeev@linux.ibm.com>,
linux-s390@vger.kernel.org, kvm@vger.kernel.org,
"Vasily Gorbik" <gor@linux.ibm.com>
Subject: Re: [PATCH v7 08/10] s390/vfio_ccw: move cp cleanup out of not operational
Date: Mon, 27 Jul 2026 20:04:15 +0000 [thread overview]
Message-ID: <20260727200416.383341F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260727192230.2715207-9-farman@linux.ibm.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [Critical] Concurrent execution of `cp_free()` via `notoper_work` without synchronization leads to data races and double-free of channel program resources.
- [High] Canceling `notoper_work` during device release or close permanently leaks channel program resources if the work is pending.
Pre-existing issues:
- [Critical] A TOCTOU race in `vfio_ccw_sch_event()` can queue `notoper_work` on a freed `private` structure during concurrent device removal.
--
--- Patch [8]: [PATCH v7 08/10] s390/vfio_ccw: move cp cleanup out of not operational ---
commit 553f8e3a76925556dafb452c43ea6719ddd97d0b
Author: Eric Farman <farman@linux.ibm.com>
s390/vfio_ccw: move cp cleanup out of not operational
The fsm_notoper() routine is called when the device has been lost, and is
(by definition) no longer operational. Push the cleanup of the private->cp
resources to a workqueue.
Cc: stable@vger.kernel.org
> diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
> index 1a095085bc728..c197ad5ab5805 100644
> --- a/drivers/s390/cio/vfio_ccw_drv.c
> +++ b/drivers/s390/cio/vfio_ccw_drv.c
[ ... ]
> @@ -125,6 +125,15 @@ void vfio_ccw_crw_todo(struct work_struct *work)
> eventfd_signal(private->crw_trigger);
> }
>
> +void vfio_ccw_notoper_todo(struct work_struct *work)
> +{
> + struct vfio_ccw_private *private;
> +
> + private = container_of(work, struct vfio_ccw_private, notoper_work);
> +
> + cp_free(&private->cp);
> +}
[Severity: Critical]
Does this introduce a double-free race condition? The new workqueue
callback invokes cp_free() asynchronously without acquiring io_mutex or
the subchannel lock.
Concurrently, fsm_close() might also execute and call cp_free(). Since
cp_free() checks and updates the initialized flag locklessly:
drivers/s390/cio/vfio_ccw_cp.c:cp_free() {
...
if (!cp->initialized)
return;
cp->initialized = false;
...
}
Could both threads proceed to double-free the channel program resources and
double-unpin guest memory pages?
> diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c
> index 4d7988ea47ef0..4d47a3c7b9a06 100644
> --- a/drivers/s390/cio/vfio_ccw_fsm.c
> +++ b/drivers/s390/cio/vfio_ccw_fsm.c
> @@ -170,8 +170,7 @@ static void fsm_notoper(struct vfio_ccw_private *private,
> css_sched_sch_todo(sch, SCH_TODO_UNREG);
> private->state = VFIO_CCW_STATE_NOT_OPER;
>
> - /* This is usually handled during CLOSE event */
> - cp_free(&private->cp);
> + queue_work(vfio_ccw_work_q, &private->notoper_work);
[Severity: Critical]
This is a pre-existing issue, but could this queue_work() trigger a
use-after-free due to a race with device removal?
In vfio_ccw_sch_event(), the private structure is fetched locklessly:
drivers/s390/cio/vfio_ccw_drv.c:vfio_ccw_sch_event() {
struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
...
}
Concurrently, if userspace initiates device removal, vfio_ccw_mdev_remove()
clears drvdata and frees the private structure via vfio_put_device(). If
vfio_ccw_sch_event() is preempted after fetching the pointer but before
acquiring the lock, could it pass a freed private pointer into
vfio_ccw_fsm_event(), which then queues the notoper_work?
> }
>
> /*
> diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
> index bd488e40e1531..8ec6b175d9914 100644
> --- a/drivers/s390/cio/vfio_ccw_ops.c
> +++ b/drivers/s390/cio/vfio_ccw_ops.c
[ ... ]
> @@ -139,6 +140,7 @@ static void vfio_ccw_mdev_release_dev(struct vfio_device *vdev)
> /* Should be empty, but just in case */
> cancel_work_sync(&private->io_work);
> cancel_work_sync(&private->crw_work);
> + cancel_work_sync(&private->notoper_work);
[Severity: High]
Does canceling the deferred cleanup synchronously here leak the channel
program resources?
If the device transitions to VFIO_CCW_STATE_NOT_OPER, queue_work() schedules
this cleanup. If the device is subsequently closed or released before the
workqueue executes, cancel_work_sync() will abort the pending cleanup.
Furthermore, because the state is VFIO_CCW_STATE_NOT_OPER, the normal close
handler is bypassed:
drivers/s390/cio/vfio_ccw_fsm.c:vfio_ccw_jumptable
[VFIO_CCW_STATE_NOT_OPER][VFIO_CCW_EVENT_CLOSE] = fsm_nop,
Does this completely bypass cp_free() and permanently leak the allocations
and pinned guest memory pages?
>
> kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727192230.2715207-1-farman@linux.ibm.com?part=8
next prev parent reply other threads:[~2026-07-27 20:04 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-27 19:22 [PATCH v7 00/10] s390/vfio_ccw fixes Eric Farman
2026-07-27 19:22 ` [PATCH v7 01/10] s390/vfio_ccw: free all memory if cp_init() fails Eric Farman
2026-07-27 19:58 ` sashiko-bot
2026-07-27 19:22 ` [PATCH v7 02/10] s390/vfio_ccw: limit the number of channel program segments Eric Farman
2026-07-27 19:52 ` sashiko-bot
2026-07-27 19:22 ` [PATCH v7 03/10] s390/vfio_ccw: fix out of bounds check on CCW array Eric Farman
2026-07-27 19:53 ` sashiko-bot
2026-07-27 19:22 ` [PATCH v7 04/10] s390/vfio_ccw: ensure first IDAW remains constant Eric Farman
2026-07-27 19:59 ` sashiko-bot
2026-07-27 19:22 ` [PATCH v7 05/10] s390/vfio_ccw: calculate idal length based on idaw type Eric Farman
2026-07-27 19:54 ` sashiko-bot
2026-07-27 19:22 ` [PATCH v7 06/10] s390/vfio_ccw: ensure index for read/write regions are within range Eric Farman
2026-07-27 20:03 ` sashiko-bot
2026-07-27 19:22 ` [PATCH v7 07/10] s390/vfio_ccw: cancel existing workqueues Eric Farman
2026-07-27 20:02 ` sashiko-bot
2026-07-27 21:54 ` Matthew Rosato
2026-07-27 19:22 ` [PATCH v7 08/10] s390/vfio_ccw: move cp cleanup out of not operational Eric Farman
2026-07-27 20:04 ` sashiko-bot [this message]
2026-07-27 21:54 ` Matthew Rosato
2026-07-27 19:22 ` [PATCH v7 09/10] s390/vfio_ccw: selectively expand io_mutex Eric Farman
2026-07-27 20:12 ` sashiko-bot
2026-07-27 19:22 ` [PATCH v7 10/10] s390/vfio_ccw: implement a crw lock Eric Farman
2026-07-27 20:07 ` sashiko-bot
2026-07-27 21:35 ` Farhan Ali
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=20260727200416.383341F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=farman@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@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.