Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Anthony Krowiak" <akrowiak@linux.ibm.com>
Cc: "Vasily Gorbik" <gor@linux.ibm.com>,
	linux-s390@vger.kernel.org, kvm@vger.kernel.org,
	"Heiko Carstens" <hca@linux.ibm.com>,
	"Alexander Gordeev" <agordeev@linux.ibm.com>
Subject: Re: [PATCH v4 11/15] s390/vfio-ap: Transition device migration state to STOP
Date: Tue, 07 Jul 2026 09:34:09 +0000	[thread overview]
Message-ID: <20260707093409.8FD521F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260707090226.3206695-12-akrowiak@linux.ibm.com>

Thank you for your contribution! Sashiko AI review found 8 potential issue(s) to consider:
- [Critical] Fragmented or malformed writes to the resuming file descriptor trigger severe memory corruption bugs (Double Free, NULL Dereference, Leak).
- [Critical] Insufficient length check in allocate_ap_config allows out-of-bounds heap read during post-copy validation.
- [Critical] Uninitialized stack variable `guest_matrix` is used to configure the guest AP matrix.
- [High] Improper handling of RESUMING -> STOP transition enables state machine bypass, lack of validation, and memory leaks.
- [High] The `config_sz` field in the serialized `struct vfio_ap_config` is never set during the STOP_COPY phase, breaking allocation logic on the target host.
- [High] Transitions between RUNNING and STOP states incorrectly return `-EOPNOTSUPP`.
- [High] Missing locking in `vfio_ap_release_mig_file` leads to a TOCTOU data race and Use-After-Free of migration state pointers.
- [Medium] `vfio_ap_release_migration_data` leaks `ap_config` when the device is closed.
--

--- Patch [11]: [PATCH v4 11/15] s390/vfio-ap: Transition device migration state to STOP ---
commit 07eb7dcf0820cdb3df175eeebfcfafc28e35382d
Author: Anthony Krowiak <akrowiak@linux.ibm.com>

s390/vfio-ap: Transition device migration state to STOP

This commit modifies the VFIO AP migration state machine to return NULL
when transitioning to the STOP state from RESUMING or STOP_COPY. It
removes the unsupported error return to allow the migration framework to
clean up the file streams.

> diff --git a/drivers/s390/crypto/vfio_ap_migration.c b/drivers/s390/crypto/vfio_ap_migration.c
> index 9cd1e7a3f7430..1b526b743ad02 100644
> --- a/drivers/s390/crypto/vfio_ap_migration.c
> +++ b/drivers/s390/crypto/vfio_ap_migration.c
> @@ -1159,12 +1159,17 @@ vfio_ap_transition_to_state(struct ap_matrix_mdev *matrix_mdev,
>  		return filp;
>  	}
>  
> +	/*
> +	 * Terminates the data transfer session of the vfio-ap device state
> +	 * between the source and target hosts. Since the vfio-ap device does
> +	 * not virtualize a DMA device, there is no internal device state to
> +	 * incorporate into the vfio-ap device on the target.
> +	 */
>  	if ((cur_state == VFIO_DEVICE_STATE_RESUMING &&
>  	     new_state == VFIO_DEVICE_STATE_STOP) ||
>  	    (cur_state == VFIO_DEVICE_STATE_STOP_COPY &&
>  	     new_state == VFIO_DEVICE_STATE_STOP)) {
> -		/* TODO */
> -		return ERR_PTR(-EOPNOTSUPP);
> +		return NULL;

[Severity: High]
Does returning NULL here without explicitly closing the file or clearing
mig_data->resuming_mig_state.filp allow a state machine bypass?

If a misbehaving userspace keeps the file descriptor open and transitions
the device back to RUNNING, it appears it could bypass migration state
machine constraints. Because vfio_ap_resuming_write() only checks that the
file descriptor matches resuming_mig_state.filp rather than verifying the
current mig_state, could userspace overwrite the active AP configuration
while the device is fully running?

Also, would initiating another migration cycle blindly overwrite filp and
cause a memory leak?

>  	}
>  
>  	if ((cur_state == VFIO_DEVICE_STATE_STOP &&

[Severity: High]
Are transitions between RUNNING and STOP states incorrectly returning
-EOPNOTSUPP in this adjacent block?

drivers/s390/crypto/vfio_ap_migration.c:vfio_ap_transition_to_state() {
	...
	if ((cur_state == VFIO_DEVICE_STATE_STOP &&
	     new_state == VFIO_DEVICE_STATE_RUNNING) ||
	    (cur_state == VFIO_DEVICE_STATE_RUNNING &&
	     new_state == VFIO_DEVICE_STATE_STOP)) {
		/* TODO */
		return ERR_PTR(-EOPNOTSUPP);
	}
	...
}

The VFIO migration specification mandates that devices must support
transitions between VFIO_DEVICE_STATE_RUNNING and VFIO_DEVICE_STATE_STOP.
When vfio_mig_get_next_state() attempts to transition the device through the
state machine, will this stub logic instantly fail and render the device
migration feature broken?

[Severity: Critical]
Can fragmented or malformed writes to the resuming file descriptor trigger
memory corruption?

In vfio_ap_resuming_write():

	if (*pos + len == cfg_sz) {
		ret = do_post_copy_validation(mdev_name, ap_config);
		...
		mig_data->resuming_mig_state.ap_config = ap_config;
	}

If a short write occurs where len < sizeof(config), it appears ap_config is
allocated locally but not saved to mig_data because *pos + len == cfg_sz
evaluates to false, causing a memory leak.

Then, if a subsequent write fetches the unsaved (NULL) pointer and passes it
to reallocate_ap_config():

	cur_cfg_sz = ap_config->config_sz;

Could this unconditionally dereference ap_config, causing a kernel crash?

Alternatively, if a full write is followed by an extra write,
reallocate_ap_config() executes krealloc(). If the bounds check fails and
cleanup frees the local ap_config pointer, does
mig_data->resuming_mig_state.ap_config still hold the freed pointer, leading
to a Double Free when vfio_ap_release_resuming_file() is called?

[Severity: Critical]
Is allocate_ap_config() allocating an undersized buffer if the input payload
is smaller than expected?

drivers/s390/crypto/vfio_ap_migration.c:allocate_ap_config() {
	...
	} else {
		config_size = len;
	}

	*ap_config = kzalloc(config_size, GFP_KERNEL_ACCOUNT);
	...
}

If userspace writes a payload strictly smaller than sizeof(struct
vfio_ap_config), and vfio_ap_resuming_write() considers the configuration
fully written, the undersized buffer is passed to do_post_copy_validation().

In queues_available_on_target_system():

	for (int i = 0; i < source_config->num_queues; i++) {
		apqn = source_config->qinfo[i].apqn;

Does this allow an out-of-bounds heap read based on the untrusted
and undersized config buffer?

[Severity: Critical]
Could the stack variable guest_matrix be used without initialization?

drivers/s390/crypto/vfio_ap_migration.c:vfio_ap_resuming_write() {
	...
	struct ap_matrix guest_matrix;
	...
		setup_ap_matrix_from_ap_config(mdev_name, ap_config,
					       &guest_matrix);
	...
}

In setup_ap_matrix_from_ap_config():

		if (!test_bit_inv(apid, guest_matrix->apm))
			set_bit_inv(apid, guest_matrix->apm);

It looks like guest_matrix is declared on the stack without being
zero-initialized, and setup_ap_matrix_from_ap_config() only sets individual
bits. Does this leave uninitialized bits in the apm, aqm, and adm bitmaps,
potentially granting the target guest hardware access to unauthorized AP
adapters and domains?

[Severity: High]
Are we missing the initialization of the config_sz field during the
STOP_COPY phase?

drivers/s390/crypto/vfio_ap_migration.c:vfio_ap_get_config() {
	ap_configuration = kzalloc(*ap_config_size, GFP_KERNEL_ACCOUNT);
	if (!ap_configuration)
		return -ENOMEM;

	ap_configuration->num_queues = num_queues;
	...
}

The allocation succeeds, but it doesn't look like
ap_configuration->config_sz is initialized before returning it to be copied
to user space. If this structure is transferred and the target host receives
config_sz == 0, would a fragmented write on the target erroneously call
krealloc() to shrink the buffer to merely len bytes, breaking fragmented
migrations?

[Severity: High]
Is there a locking issue in vfio_ap_release_mig_file() that could lead to a
data race and Use-After-Free?

drivers/s390/crypto/vfio_ap_migration.c:vfio_ap_release_mig_file() {
	...
	if (!matrix_mdev || !matrix_mdev->mig_data)
		return -ENODEV;

	if (filp == matrix_mdev->mig_data->stop_copy_mig_file)
		vfio_ap_release_stop_copy_file(matrix_mdev->mig_data);
	...
}

This accesses matrix_mdev->mig_data entirely locklessly. Since
vfio_ap_release_migration_data() and vfio_ap_transition_to_state() modify
and free this data under matrix_dev->mdevs_lock, could a concurrent close of
the migration file descriptor result in a Time-of-Check to Time-of-Use race?

If vfio_ap_release_mig_file() evaluates matrix_mdev->mig_data as valid but a
concurrent teardown thread kfrees it, would this result in a Use-After-Free
when dereferencing mig_data->stop_copy_mig_file?

[Severity: Medium]
Will vfio_ap_release_migration_data() leak ap_config when the device is
closed?

drivers/s390/crypto/vfio_ap_migration.c:vfio_ap_release_migration_data() {
	if (!matrix_mdev->mig_data)
		return;

	kfree(matrix_mdev->mig_data);
	matrix_mdev->mig_data = NULL;
}

This frees mig_data without cleaning up the dynamically allocated
mig_data->resuming_mig_state.ap_config buffer inside it.

Because the pointer is nulled, when VFS eventually drops the final reference
to the RESUMING migration file, vfio_ap_release_mig_file() will abort early
with -ENODEV. Will this bypass the kfree call within
vfio_ap_release_resuming_file() and permanently leak the allocated ap_config
memory?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260707090226.3206695-1-akrowiak@linux.ibm.com?part=11

  reply	other threads:[~2026-07-07  9:34 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-07  9:02 [PATCH v4 00/15] s390/vfio-ap: Add live guest migration support Anthony Krowiak
2026-07-07  9:02 ` [PATCH v4 01/15] s390/vfio-ap: Provide function to get the number of queues assigned to mdev Anthony Krowiak
2026-07-07  9:02 ` [PATCH v4 02/15] s390/vfio-ap: Data structures for facilitating vfio device migration Anthony Krowiak
2026-07-07  9:09   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 03/15] s390/vfio-ap: Functions to initialize/release vfio device migration data Anthony Krowiak
2026-07-07  9:18   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 04/15] s390/vfio-ap: Reset migration state in VFIO_DEVICE_RESET ioctl handler Anthony Krowiak
2026-07-07  9:15   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 05/15] s390-vfio-ap: Callback to get/set vfio device mig state during guest migration Anthony Krowiak
2026-07-07  9:18   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 06/15] s390/vfio-ap: Transition guest migration state from STOP to STOP_COPY Anthony Krowiak
2026-07-07  9:24   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 07/15] s390/vfio-ap: File ops called to save the vfio device migration state Anthony Krowiak
2026-07-07  9:22   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 08/15] s390/vfio-ap: Transition device migration state from STOP to RESUMING Anthony Krowiak
2026-07-07  9:23   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 09/15] s390/vfio-ap: Add method to set a new guest AP configuration Anthony Krowiak
2026-07-07  9:24   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 10/15] s390/vfio-ap: File ops called to resume the vfio device migration Anthony Krowiak
2026-07-07  9:26   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 11/15] s390/vfio-ap: Transition device migration state to STOP Anthony Krowiak
2026-07-07  9:34   ` sashiko-bot [this message]
2026-07-07  9:02 ` [PATCH v4 12/15] s390/vfio-ap: Transition device migration state from STOP to RUNNING and vice versa Anthony Krowiak
2026-07-07  9:33   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 13/15] s390/vfio-ap: Callback to get the size of data to be migrated during guest migration Anthony Krowiak
2026-07-07  9:32   ` sashiko-bot
2026-07-07  9:02 ` [PATCH v4 14/15] s390/vfio-ap: Add 'migratable' feature to sysfs 'features' attribute Anthony Krowiak
2026-07-07  9:02 ` [PATCH v4 15/15] s390/vfio-ap: Add live guest migration chapter to vfio-ap.rst Anthony Krowiak
2026-07-07  9:27   ` 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=20260707093409.8FD521F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=akrowiak@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