Linux s390 Architecture development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Steffen Eiden" <seiden@linux.ibm.com>
Cc: linux-s390@vger.kernel.org, "Vasily Gorbik" <gor@linux.ibm.com>,
	"Oliver Upton" <oupton@kernel.org>,
	"Marc Zyngier" <maz@kernel.org>,
	"Heiko Carstens" <hca@linux.ibm.com>,
	kvmarm@lists.linux.dev,
	"Alexander Gordeev" <agordeev@linux.ibm.com>,
	kvm@vger.kernel.org
Subject: Re: [PATCH v5 01/31] vfio: Use file-based reference counting for KVM
Date: Fri, 31 Jul 2026 13:27:37 +0000	[thread overview]
Message-ID: <20260731132737.DB4B51F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260731130902.654679-2-seiden@linux.ibm.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] Architectural Use-After-Free and Type Confusion due to dangling `kvm->file` and `get_file_active` API misuse.
- [High] The KVM file reference is permanently leaked in `vfio_ap_mdev_set_kvm()` when KVM crypto is unavailable.
- [Low] Unused parameter 'file' added to `kvm_ioctl_create_device`.
--

--- Patch [1]: [PATCH v5 01/31] vfio: Use file-based reference counting for KVM ---
commit 0d6533aa3c5f21c080ec0d95c626b95fd5fb711d
Author: Steffen Eiden <seiden@linux.ibm.com>

vfio: Use file-based reference counting for KVM

Replace manual module reference counting with file-based reference
counting for KVM integration. Previously, VFIO used symbol_get() to
obtain function pointers for kvm_get_kvm_safe() and kvm_put_kvm(),
then manually tracked module references through these symbols. This
approach required storing the put_kvm function pointer in each device
and carefully managing symbol references.

Pass struct file pointers instead of struct kvm pointers throughout the
VFIO-KVM interface. This leverages the kernel's existing file reference
counting mechanism via get_file_active() and fput(), eliminating the
need for manual module reference tracking. The file->private_data field
provides access to the underlying struct kvm when needed.

This simplifies the code and removes all remaining externally exported
symbols for KVM, paving the path for a second concurrent KVM module.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>

> diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
> index 44b3a1dcc1b36..177c8f5ab6b91 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
[ ... ]
> @@ -1815,13 +1816,26 @@ static const struct attribute_group *vfio_ap_mdev_attr_groups[] = {
>   * @matrix_mdev: a mediated matrix device
>   * @kvm: reference to KVM instance
>   *
> - * Return: 0 if no other mediated matrix device has a reference to @kvm;
> - * otherwise, returns an -EPERM.
> + * Returns: 0 if the reference to kvm is successfully retrieved from @kvm_file
> + * and set into @matrix_mdev; otherwise, returns:
> + *	-ENOENT if a reference to kvm could not be retrieved from @kvm_file
> + *	-EPERM if another mediated matrix device already has a reference to the same kvm instance
>   *
>   */
>  static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
> -				struct kvm *kvm)
> +				struct file *kvm_file)
>  {
> +	struct file *kvm_file_ref __free(fput) = NULL;
>  	struct ap_matrix_mdev *m;
> +	struct kvm *kvm;
> +
> +	kvm_file_ref = get_file_active(&kvm_file);

[Severity: Critical]
Because kvm_file is passed by value, &kvm_file is a stack address. Doesn't
this bypass the RCU validation in get_file_active()? Since it checks the
address on the stack, the RCU validation will always succeed even if the
underlying struct file was reallocated.

> +	if (!kvm_file_ref)
> +		return -ENOENT;
> +
> +	kvm = kvm_file->private_data;
> +	if (!kvm)
> +		return -ENOENT;
>  
>  	if (kvm->arch.crypto.crycbd) {
>  		down_write(&kvm->arch.crypto.pqap_hook_rwsem);
[ ... ]
> @@ -1837,13 +1851,13 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
>  			}
>  		}
>  
> -		kvm_get_kvm(kvm);
>  		matrix_mdev->kvm = kvm;
>  		vfio_ap_mdev_update_guest_apcb(matrix_mdev);
>  
>  		release_update_locks_for_kvm(kvm);
>  	}
>  
> +	no_free_ptr(kvm_file_ref);
>  	return 0;
>  }

[Severity: High]
Does this unconditionally leak the file reference if kvm->arch.crypto.crycbd
is false?

In the false case, matrix_mdev->kvm is not set, but no_free_ptr(kvm_file_ref)
is still called, which inhibits the __free(fput) cleanup. Later, when the
device is released, vfio_ap_mdev_unset_kvm() will see a NULL matrix_mdev->kvm
and do nothing, permanently leaking the struct file reference.

> diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
> index ed538aebb0b8e..8fad1ca1189f8 100644
> --- a/drivers/vfio/vfio_main.c
> +++ b/drivers/vfio/vfio_main.c
[ ... ]
> @@ -448,35 +448,13 @@ void vfio_unregister_group_dev(struct vfio_device *device)
>  EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
>  
>  #if IS_ENABLED(CONFIG_KVM)
> -void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm)
> +void vfio_device_get_kvm_safe(struct vfio_device *device, struct file *kvm)
>  {
> -	void (*pfn)(struct kvm *kvm);
> -	bool (*fn)(struct kvm *kvm);
> -	bool ret;
> -
>  	lockdep_assert_held(&device->dev_set->lock);
>  
> -	if (!kvm)
> -		return;
> -
> -	pfn = symbol_get(kvm_put_kvm);
> -	if (WARN_ON(!pfn))
> +	if (!get_file_active(&kvm))
>  		return;

[Severity: Critical]
Does this usage of get_file_active() defeat its RCU reallocation safety
checks? Similar to the vfio_ap_mdev_set_kvm() case above, kvm is a stack
variable here, so get_file_active() is checking a stack address rather than
the original pointer location.

If the struct file is reallocated (which can happen because the weak back
reference kvm->file can outlive the file descriptor, as noted below),
couldn't this increment the f_count of an arbitrarily reallocated file and
lead to type confusion?

> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 45e784462ec6e..994cb40cf2efe 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
[ ... ]
> @@ -4802,7 +4802,7 @@ void kvm_unregister_device_ops(u32 type)
>  		kvm_device_ops_table[type] = NULL;
>  }
>  
> -static int kvm_ioctl_create_device(struct kvm *kvm,
> +static int kvm_ioctl_create_device(struct file *file, struct kvm *kvm,
>  				   struct kvm_create_device *cd)
>  {
>  	const struct kvm_device_ops *ops;

[Severity: Low]
Is the new file parameter intended to be used in this function? It looks
like the function body still relies on kvm_get_kvm(kvm) and ignores this
argument.

[ ... ]
> @@ -5508,6 +5517,10 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
>  	 * cases it will be called by the final fput(file) and will take
>  	 * care of doing kvm_put_kvm(kvm).
>  	 */
> +
> +	/* Store back-reference for VFIO and other subsystems */
> +	kvm->file = file;
> +
>  	kvm_uevent_notify_change(KVM_EVENT_CREATE_VM, kvm);
>  
>  	fd_install(fd, file);

[Severity: Critical]
Could this lead to a use-after-free or type confusion?

When userspace closes the KVM VM fd, the file is destroyed and freed by RCU.
However, the kvm object remains alive if kvm_vfio holds a reference to it
(since kvm_vfio_file_add passes dev->kvm->file to VFIO). This would leave
kvm->file as a dangling pointer.

If a VFIO operation later calls vfio_device_get_kvm_safe() on that dangling
pointer, it might operate on a reallocated struct file.

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

  reply	other threads:[~2026-07-31 13:27 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31 13:08 [PATCH v5 00/31] KVM: s390: Introduce arm64 KVM Steffen Eiden
2026-07-31 13:08 ` [PATCH v5 01/31] vfio: Use file-based reference counting for KVM Steffen Eiden
2026-07-31 13:27   ` sashiko-bot [this message]
2026-07-31 14:54   ` Steffen Eiden
2026-07-31 16:15     ` Sean Christopherson
2026-07-31 13:08 ` [PATCH v5 02/31] KVM: Make device name configurable Steffen Eiden
2026-07-31 13:26   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 03/31] KVM: Allow KVM implementations to switch off MMIO independent of Kconfig Steffen Eiden
2026-07-31 13:28   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 04/31] arm64: Use proper include variant Steffen Eiden
2026-07-31 13:16   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 05/31] arm64: ptrace: Use constants for compat register numbers Steffen Eiden
2026-07-31 13:21   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 06/31] arm64/sysreg: Convert SPSR_ELx to automatic register generation Steffen Eiden
2026-07-31 13:30   ` sashiko-bot
2026-07-31 14:17   ` Marc Zyngier
2026-07-31 14:50     ` Steffen Eiden
2026-07-31 13:08 ` [PATCH v5 07/31] KVM: arm64: Access elements of vcpu_gp_regs individually Steffen Eiden
2026-07-31 13:26   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 08/31] KVM: arm64: Use accessor functions for gprs during reset Steffen Eiden
2026-07-31 13:36   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 09/31] KVM: arm64: Refactor core-reset into a separate function Steffen Eiden
2026-07-31 13:30   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 10/31] arm64: Prepare sharing arm64 headers with s390 Steffen Eiden
2026-07-31 13:31   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 11/31] arm64: Share " Steffen Eiden
2026-07-31 13:39   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 12/31] KVM: arm64: Share arm64 code " Steffen Eiden
2026-07-31 13:43   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 13/31] KVM: s390: Prepare moving KVM/s390 to arch/s390/kvm/s390 Steffen Eiden
2026-07-31 13:37   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 14/31] KVM: s390: Move s390 kvm code into a subdirectory Steffen Eiden
2026-07-31 13:43   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 15/31] KVM: s390: Guard KVM/s390 behind CONFIG_KVM_S390 Steffen Eiden
2026-07-31 13:47   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 16/31] KVM: s390: Move PGM code definitions to asm/kvm_host.h Steffen Eiden
2026-07-31 13:42   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 17/31] KVM: s390: Prepare gmap for a second KVM implementation Steffen Eiden
2026-07-31 13:47   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 18/31] KVM: s390: gmap: Move storage key and CMMA code to kvm/s390 Steffen Eiden
2026-07-31 13:56   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 19/31] KVM: s390: gmap: Move prefix handling " Steffen Eiden
2026-07-31 13:50   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 20/31] KVM: s390: Prepare KVM/s390 for a second KVM module Steffen Eiden
2026-07-31 13:50   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 21/31] s390: Use arm64 headers Steffen Eiden
2026-07-31 13:54   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 22/31] KVM: s390: Use arm64 code Steffen Eiden
2026-07-31 13:52   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 23/31] s390: Introduce Start Arm Execution instruction Steffen Eiden
2026-07-31 14:03   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 24/31] KVM: s390: arm64: Introduce host definitions Steffen Eiden
2026-07-31 14:09   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 25/31] s390/hwcaps: Report SAE support as hwcap Steffen Eiden
2026-07-31 13:57   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 26/31] KVM: s390: Add basic arm64 kvm module Steffen Eiden
2026-07-31 14:06   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 27/31] KVM: s390: arm64: Implement required functions Steffen Eiden
2026-07-31 14:24   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 28/31] KVM: s390: arm64: Implement vm/vcpu create destroy Steffen Eiden
2026-07-31 14:18   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 29/31] KVM: s390: arm64: Implement vCPU IOCTLs Steffen Eiden
2026-07-31 14:42   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 30/31] KVM: s390: arm64: Implement basic page fault handler Steffen Eiden
2026-07-31 14:17   ` sashiko-bot
2026-07-31 13:08 ` [PATCH v5 31/31] KVM: s390: arm64: Enable KVM_ARM64 config and Kbuild Steffen Eiden
2026-07-31 14:25   ` 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=20260731132737.DB4B51F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-s390@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=seiden@linux.ibm.com \
    /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