All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Anthony Krowiak" <akrowiak@linux.ibm.com>,
	linux-s390@vger.kernel.org, kvm@vger.kernel.org
Cc: "Heiko Carstens" <hca@linux.ibm.com>,
	"Vasily Gorbik" <gor@linux.ibm.com>,
	"Alexander Gordeev" <agordeev@linux.ibm.com>,
	"Christian Borntraeger" <borntraeger@linux.ibm.com>
Subject: Re: [PATCH v11 09/14] s390/vfio-ap: File ops called to resume the vfio device migration
Date: Mon, 02 Nov 2026 17:09:48 +0000	[thread overview]
Message-ID: <sashiko-outbox-193805@kernel.org> (raw)
In-Reply-To: <20261102151604.2150055-10-akrowiak@linux.ibm.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] s390/vfio-ap: use-after-free of mig_file in vfio_ap_resuming_write()
- [High] s390/vfio-ap: fortify panic in vfio_ap_resuming_write() on chunked writes
--

commit 05b49746b964ad1916518e2c783de5c6220f1f14
Author: Anthony Krowiak <akrowiak@linux.ibm.com>

s390/vfio-ap: File ops called to resume the vfio device migration

This commit implements the write callback for the migration file stream used
during the RESUMING phase to receive and validate the source guest's AP
configuration on the destination host.

> diff --git a/drivers/s390/crypto/vfio_ap_migration.c b/drivers/s390/crypto/vfio_ap_migration.c
> index 526d83e8590d9..47f05e43b9e0e 100644
> --- a/drivers/s390/crypto/vfio_ap_migration.c
> +++ b/drivers/s390/crypto/vfio_ap_migration.c

[ ... ]

> @@ -466,11 +511,562 @@ static struct file *vfio_ap_open_file_stream(struct vfio_ap_migration_file *mig_
>  	return filp;
>  }
>  
> +static int validate_resuming_write_parms(struct vfio_ap_migration_file *mig_file,
> +					 struct file *filp, size_t len)
> +{
> +	loff_t total_len;
> +
> +	lockdep_assert_held(&mig_file->lock);
> +	lockdep_assert_held(&matrix_dev->mdevs_lock);
> +
> +	if (!len || filp->f_pos < 0)
> +		return -EINVAL;
> +
> +	if (!mig_file->matrix_mdev->mig_data)
> +		return -ENODEV;

[ ... ]

>  static ssize_t vfio_ap_resuming_write(struct file *filp, const char __user *buf,
>  				      size_t len, loff_t *pos)
>  {
> -	/* TODO */
> -	return -EOPNOTSUPP;
> +	struct vfio_ap_migration_file *mig_file;
> +	struct vfio_ap_config *ap_config;
> +	ssize_t ret;
> +	void *kbuf;

[ ... ]

> +	mig_file = filp->private_data;
> +	mutex_lock(&mig_file->lock);
> +	mutex_lock(&ap_attr_mutex);
> +	mutex_lock(&matrix_dev->mdevs_lock);
> +	pos = &filp->f_pos;
> +
> +	ret = validate_resuming_write_parms(mig_file, filp, len);
> +	if (ret)
> +		goto out_unlock;

[Severity: High]
Can this trigger a use-after-free on mig_file if the VFIO device file
descriptor is closed while the migration file descriptor remains open?

In vfio_ap_resuming_init() -> vfio_ap_open_file_stream(), filp->private_data
is set to &mig_data->resuming_mig_file, which is embedded inside
matrix_mdev->mig_data:

drivers/s390/crypto/vfio_ap_migration.c:
struct vfio_ap_migration_data {
	enum vfio_device_mig_state	mig_state;
	bool				resuming_mig_data_complete;
	struct vfio_ap_migration_file	resuming_mig_file;
	struct vfio_ap_migration_file	stop_copy_mig_file;
};

While vfio_ap_open_file_stream() calls vfio_device_try_get_registration() to
keep matrix_mdev alive until vfio_ap_release_mig_file() runs, closing the
VFIO device file descriptor invokes:

vfio_ap_mdev_close_device()
  vfio_ap_release_migration_data() {
	...
	vfio_ap_release_mig_files(matrix_mdev);
	mutex_destroy(&matrix_mdev->mig_data->stop_copy_mig_file.lock);
	mutex_destroy(&matrix_mdev->mig_data->resuming_mig_file.lock);
	kfree(matrix_mdev->mig_data);
	matrix_mdev->mig_data = NULL;
  }

Although validate_resuming_write_parms() checks
!mig_file->matrix_mdev->mig_data under matrix_dev->mdevs_lock, mig_file
itself lives inside the freed matrix_mdev->mig_data object. Calling
vfio_ap_resuming_write() after or concurrently with
vfio_ap_mdev_close_device() will lock and unlock the destroyed
mig_file->lock and dereference mig_file->matrix_mdev in freed memory.

> +
> +	ap_config = mig_file->ap_config;
> +	memcpy((char *)ap_config + *pos, kbuf, len);
> +	*pos += len;
> +
> +	/*
> +	 * Check whether we have received all the data.  We know the total
> +	 * expected size once num_queues has arrived, i.e. once *pos is past
> +	 * the fixed header.  Until then keep accumulating.
> +	 */
> +	if (*pos >= offsetofend(struct vfio_ap_config, num_queues)) {
> +		size_t expected_sz;
> +
> +		if (ap_config->num_queues > MAX_AP_QUEUES) {
> +			ret = -EINVAL;
> +			goto out_unlock;
> +		}
> +
> +		expected_sz = sizeof(struct vfio_ap_config) +
> +			      ap_config->num_queues *
> +			      sizeof(struct vfio_ap_queue_info);
> +
> +		if (*pos > (loff_t)expected_sz) {
> +			ret = -EINVAL;
> +			goto out_unlock;
> +		}

[Severity: High]
As reported by Sashiko on v9 [1], can the memcpy() in
vfio_ap_resuming_write() trigger a fortify_panic() on chunked writes when
CONFIG_FORTIFY_SOURCE and CONFIG_CC_HAS_COUNTED_BY are enabled?

In struct vfio_ap_config, qinfo[] is annotated with
__counted_by(num_queues):

struct vfio_ap_config {
	u32				magic;
	u32				version;
	u32				num_queues;
	u8				reserved[4];
	u64				adm[DIV_ROUND_UP(AP_DOMAINS, 64)];
	struct vfio_ap_queue_info	qinfo[] __counted_by(num_queues);
};

Although vfio_ap_resuming_init() initializes ap_config->num_queues to
MAX_AP_QUEUES, fortified memcpy((char *)ap_config + *pos, kbuf, len)
evaluates __struct_size((char *)ap_config + *pos) using the current value of
ap_config->num_queues in memory before the expected_sz check runs:

1. Once an earlier chunk writes the header with num_queues < MAX_AP_QUEUES,
   the dynamic object size of *ap_config shrinks to expected_sz. If a
   subsequent write() supplies more bytes than expected_sz - *pos (while
   staying within VFIO_AP_CONFIG_MAX_SIZE), memcpy() executes before the
   *pos > (loff_t)expected_sz check and calls fortify_panic() instead of
   returning -EINVAL.

2. On big-endian s390, MAX_AP_QUEUES (0x00010000) has bytes 0x00, 0x01,
   0x00, 0x00 at offsets 8..11. If an initial chunk of 10 or 11 bytes writes
   the upper two bytes of a valid num_queues < 65536 (0x00, 0x00),
   ap_config->num_queues in memory becomes 0. If the next chunk writes past
   the header into qinfo[], fortified memcpy() evaluates __struct_size()
   with ap_config->num_queues == 0 before copying the remaining bytes of
   num_queues, triggering fortify_panic() on valid migration data.

[1] https://lore.kernel.org/r/sashiko-outbox-170099@kernel.org

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

  reply	other threads:[~2026-11-02 17:09 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 15:14 [PATCH v11 00/14] s390/vfio-ap: Add live guest migration support Anthony Krowiak
2026-11-02 15:14 ` [PATCH v11 01/14] s390/vfio-ap: Provide function to get the number of queues assigned to mdev Anthony Krowiak
2026-11-02 15:23   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 02/14] s390/vfio-ap: Data structures for facilitating vfio device migration Anthony Krowiak
2026-11-02 15:29   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 03/14] s390/vfio-ap: Functions to initialize/release vfio device migration data Anthony Krowiak
2026-11-02 15:46   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 04/14] s390/vfio-ap: Reset migration state in VFIO_DEVICE_RESET ioctl handler Anthony Krowiak
2026-11-02 15:49   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 05/14] s390/vfio-ap: Callback to get/set vfio device mig state during guest migration Anthony Krowiak
2026-11-02 16:06   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 06/14] s390/vfio-ap: Transition guest migration state from STOP to STOP_COPY Anthony Krowiak
2026-11-02 16:18   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 07/14] s390/vfio-ap: File ops called to save the vfio device migration state Anthony Krowiak
2026-11-02 16:32   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 08/14] s390/vfio-ap: Transition device migration state from STOP to RESUMING Anthony Krowiak
2026-11-02 16:42   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 09/14] s390/vfio-ap: File ops called to resume the vfio device migration Anthony Krowiak
2026-11-02 17:09   ` sashiko-bot [this message]
2026-11-02 15:14 ` [PATCH v11 10/14] s390/vfio-ap: Transition device migration state to from/to STOP Anthony Krowiak
2026-11-02 17:23   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 11/14] s390/vfio-ap: Callback to get the size of data to be migrated during guest migration Anthony Krowiak
2026-11-02 17:39   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 12/14] s390/vfio-ap: Set up for vfio-ap device migration Anthony Krowiak
2026-11-02 17:57   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 13/14] s390/vfio-ap: Add 'migration' feature to sysfs 'features' attribute Anthony Krowiak
2026-11-02 18:10   ` sashiko-bot
2026-11-02 15:14 ` [PATCH v11 14/14] s390/vfio-ap: Add live guest migration chapter to vfio-ap.rst Anthony Krowiak
2026-11-02 18:19   ` 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=sashiko-outbox-193805@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=akrowiak@linux.ibm.com \
    --cc=borntraeger@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.