From: Sean Christopherson <seanjc@google.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: David Hildenbrand <david@kernel.org>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Stefan Teodorescu <fane@google.com>,
Dennis Tighe <dtighe@google.com>,
Sashiko Bot <sashiko-bot@kernel.org>,
Ackerley Tng <ackerleytng@google.com>,
Yan Zhao <yan.y.zhao@intel.com>
Subject: [PATCH v5 1/6] KVM: guest_memfd: Gracefully handle xarray errors when binding a memslot
Date: Mon, 21 Sep 2026 17:13:27 -0700 [thread overview]
Message-ID: <20260922001332.1121266-2-seanjc@google.com> (raw)
In-Reply-To: <20260922001332.1121266-1-seanjc@google.com>
If inserting a memslot into a guest_memfd's bindings xarray fails,
propagate the error back to the caller, i.e. fail memslot creation as well.
Signalling success and continuing on with memslot creation results in
use-after-free, as the guest_memfd instance will remain reachable via the
memslot after the file is freed (kvm_gmem_release() won't nullify the file
pointer due to lack of a valid binding).
Opportunistically WARN and reject binding if KVM_MEMSLOT_GMEM_ONLY is
already set, partly to guard against goofs elsewhere, but mostly so that
KVM doesn't need to worry about clobbering flags when unwinding on failure.
Regarding the unwind, the slot must be fully prepared before inserting it
into the bindings, at which point the slot becomes reachable. I.e. waiting
to update the slot in order to avoid the ugly unwind isn't an option. And
as part of the unwind, explicitly nullify the relevant bindings, as xarray
can store a subset of entries when populating a range.
Fixes: a7800aa80ea4 ("KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory")
Cc: stable@vger.kernel.org
Reported-by: Stefan Teodorescu <fane@google.com>
Reported-by: Dennis Tighe <dtighe@google.com>
Reported-by: Sashiko Bot <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260823135031.4F6DC1F000E9%40smtp.kernel.org
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Ackerley Tng <ackerleytng@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
virt/kvm/guest_memfd.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 63943aa253d4..c094611f7c7a 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -654,6 +654,9 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot,
BUILD_BUG_ON(sizeof(gpa_t) != sizeof(offset));
BUILD_BUG_ON(sizeof(gfn_t) != sizeof(slot->gmem.pgoff));
+ if (WARN_ON_ONCE(slot->flags & KVM_MEMSLOT_GMEM_ONLY))
+ return -EINVAL;
+
file = fget(fd);
if (!file)
return -EBADF;
@@ -692,7 +695,13 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot,
if (kvm_gmem_supports_mmap(inode))
slot->flags |= KVM_MEMSLOT_GMEM_ONLY;
- xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNEL);
+ r = xa_err(xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNEL));
+ if (r) {
+ xa_store_range(&f->bindings, start, end - 1, NULL, GFP_KERNEL);
+ slot->gmem.file = NULL;
+ slot->gmem.pgoff = 0;
+ slot->flags &= ~KVM_MEMSLOT_GMEM_ONLY;
+ }
filemap_invalidate_unlock(inode->i_mapping);
/*
@@ -700,7 +709,6 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot,
* not the other way 'round. Active bindings are invalidated if the
* file is closed before memslots are destroyed.
*/
- r = 0;
err:
fput(file);
return r;
--
2.55.0.1082.g2b9226bbc0-goog
next prev parent reply other threads:[~2026-09-22 0:13 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 0:13 [PATCH v5 0/6] KVM: guest_memfd: Fix binding bugs Sean Christopherson
2026-09-22 0:13 ` Sean Christopherson [this message]
2026-09-22 0:13 ` [PATCH v5 2/6] KVM: Use goto to handle errors during memslot preparation Sean Christopherson
2026-09-22 0:13 ` [PATCH v5 3/6] KVM: Only bind memslot to guest_memfd instance for CREATE operations Sean Christopherson
2026-09-22 0:13 ` [PATCH v5 4/6] KVM: guest_memfd: Split bind() into prepare()+commit() phases Sean Christopherson
2026-09-22 0:13 ` [PATCH v5 5/6] KVM: guest_memfd: Establish memslot<=>guest_memfd bindings *after* memslot is ready Sean Christopherson
2026-09-22 0:13 ` [PATCH v5 6/6] KVM: guest_memfd: Drop superfluous WRITE_ONCE() when binding a memslot Sean Christopherson
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=20260922001332.1121266-2-seanjc@google.com \
--to=seanjc@google.com \
--cc=ackerleytng@google.com \
--cc=david@kernel.org \
--cc=dtighe@google.com \
--cc=fane@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=sashiko-bot@kernel.org \
--cc=yan.y.zhao@intel.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
all inboxes | Powered by JetHome®