From: sashiko-bot@kernel.org
To: "Eric Farman" <farman@linux.ibm.com>
Cc: "Alexander Gordeev" <agordeev@linux.ibm.com>,
"Vasily Gorbik" <gor@linux.ibm.com>,
"Heiko Carstens" <hca@linux.ibm.com>,
linux-s390@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH v2 4/7] s390/vfio_ccw: ensure first IDAW remains constant
Date: Mon, 20 Jul 2026 20:33:59 +0000 [thread overview]
Message-ID: <20260720203400.7328E1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260720201931.976660-5-farman@linux.ibm.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [Critical] This problem wasn't introduced by this patch, but concurrent execution of a device reset or DMA unmap with an active I/O request leads to a critical use-after-free and data corruption of the channel program structures.
- [High] This problem wasn't introduced by this patch, but the IDAL read length calculation in `get_guest_idal()` for Format-1 IDAWs incorrectly calculates the length as if they were 64-bit IDAWs, leading to an out-of-bounds read from guest memory.
--
--- Patch [4]: [PATCH v2 4/7] s390/vfio_ccw: ensure first IDAW remains constant ---
commit d9b51975a2a2546c96fb0396ccf078c5c296fe37
Author: Eric Farman <farman@linux.ibm.com>
s390/vfio_ccw: ensure first IDAW remains constant
This patch ensures the first IDAW in a list remains constant by verifying
its address between reads, and returning an error if a mismatch is found.
This helps maintain a consistent set of IDAWs for I/O operations.
> diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
> index ce61858c82eb6..c6f0264fb5d33 100644
> --- a/drivers/s390/cio/vfio_ccw_cp.c
> +++ b/drivers/s390/cio/vfio_ccw_cp.c
> @@ -533,6 +533,7 @@ static dma64_t *get_guest_idal(struct ccw1 *ccw, struct channel_program *cp, int
> &container_of(cp, struct vfio_ccw_private, cp)->vdev;
> dma64_t *idaws;
> dma32_t *idaws_f1;
> + u64 first_idaw;
> int idal_len = idaw_nr * sizeof(*idaws);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Severity: High]
This is a pre-existing issue, but the IDAL read length calculation in
get_guest_idal() for Format-1 IDAWs incorrectly calculates the length as if
they were 64-bit IDAWs, leading to an out-of-bounds read from guest memory.
Because Format-1 IDAWs are actually 32 bits (4 bytes) long, this instructs
vfio_dma_rw() to read exactly twice the valid IDAL size.
If the IDAL resides near the boundary of the guest's mapped IOMMU DMA region,
this over-read spans into an unmapped area, causing vfio_dma_rw() to reject
the read and fail the legitimate channel program.
Does this code need to calculate the length based on the actual IDAW size
instead of the host's 8-byte target struct dma64_t?
> int idaw_size = idal_is_2k(cp) ? PAGE_SIZE / 2 : PAGE_SIZE;
> int idaw_mask = ~(idaw_size - 1);
[ ... ]
Additionally, there is another regression present in the state machine:
[Severity: Critical]
This is a pre-existing issue, but concurrent execution of a device reset or
DMA unmap with an active I/O request leads to a use-after-free and data
corruption of the channel program structures.
If an unprivileged guest triggers an I/O operation, invoking
vfio_ccw_mdev_write_io_region() in the host, this function takes
private->io_mutex and pushes VFIO_CCW_EVENT_IO_REQ to the state machine,
invoking fsm_io_request().
Here, private->state is set to VFIO_CCW_STATE_CP_PROCESSING, and
cp_init()/cp_prefetch() are called without holding any locks:
drivers/s390/cio/vfio_ccw_fsm.c:fsm_io_request()
private->state = VFIO_CCW_STATE_CP_PROCESSING;
//...
io_region->ret_code = cp_init(&private->cp, orb);
//...
io_region->ret_code = cp_prefetch(&private->cp);
Concurrently, if the guest alters its IOMMU mappings, it triggers
vfio_ccw_dma_unmap() on the host. This callback checks cp_iova_pinned() without
holding any locks and then executes vfio_ccw_mdev_reset(), which pushes
VFIO_CCW_EVENT_CLOSE to the state machine without acquiring private->io_mutex:
drivers/s390/cio/vfio_ccw_ops.c:vfio_ccw_mdev_reset()
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_CLOSE);
Since the state is currently CP_PROCESSING, this routes to fsm_close(), which
unconditionally frees the structures concurrently with the active initialization
routine:
drivers/s390/cio/vfio_ccw_fsm.c:fsm_close()
cp_free(&private->cp);
Can this sequence actually occur and cause cp_free() to free the ccwchain
memory while cp_prefetch() is actively modifying it? Should these events be
serialized to prevent this?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720201931.976660-1-farman@linux.ibm.com?part=4
next prev parent reply other threads:[~2026-07-20 20:34 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 20:19 [PATCH v2 0/7] s390/vfio_ccw fixes Eric Farman
2026-07-20 20:19 ` [PATCH v2 1/7] s390/vfio_ccw: free all memory if cp_init() fails Eric Farman
2026-07-20 20:31 ` sashiko-bot
2026-07-20 21:48 ` Farhan Ali
2026-07-20 20:19 ` [PATCH v2 2/7] s390/vfio_ccw: limit the number of channel program segments Eric Farman
2026-07-20 20:30 ` sashiko-bot
2026-07-20 20:53 ` Eric Farman
2026-07-20 20:19 ` [PATCH v2 3/7] s390/vfio_ccw: fix out of bounds check on CCW array Eric Farman
2026-07-20 20:38 ` sashiko-bot
2026-07-20 20:19 ` [PATCH v2 4/7] s390/vfio_ccw: ensure first IDAW remains constant Eric Farman
2026-07-20 20:33 ` sashiko-bot [this message]
2026-07-20 20:19 ` [PATCH v2 5/7] s390/vfio_ccw: ensure index for read/write regions are within range Eric Farman
2026-07-20 20:40 ` sashiko-bot
2026-07-20 20:19 ` [PATCH v2 6/7] s390/vfio_ccw: implement a channel program lock Eric Farman
2026-07-20 20:39 ` sashiko-bot
2026-07-20 20:19 ` [PATCH v2 7/7] s390/vfio_ccw: implement a crw lock Eric Farman
2026-07-20 20:47 ` 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=20260720203400.7328E1F000E9@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox