KVM: Harden and prepare for modifying existing guest_memfd memslots

Unbind guest_memfd memslots if KVM commits a MOVE or FLAGS_ONLY memslot
change to harden against use-after-free, and to prepare for eventually
supporting dirty logging on guest_memfd memslots, at which point
FLAGS_ONLY changes will be expected/supported.

Add two separate WARNs, once to yell if a guest_memfd memslot is moved
(which KVM is never expected to allow/support), and again if the unbind()
is triggered, to help detect uAPI goofs prior to deliberately allowing
FLAGS_ONLY changes.

Link: https://patch.msgid.link/20251202020334.1171351-3-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
Sean Christopherson 2025-12-01 18:03:34 -08:00
parent 9935df5333
commit af62fe2494

View file

@ -1748,6 +1748,12 @@ static void kvm_commit_memory_region(struct kvm *kvm,
kvm_free_memslot(kvm, old);
break;
case KVM_MR_MOVE:
/*
* Moving a guest_memfd memslot isn't supported, and will never
* be supported.
*/
WARN_ON_ONCE(old->flags & KVM_MEM_GUEST_MEMFD);
fallthrough;
case KVM_MR_FLAGS_ONLY:
/*
* Free the dirty bitmap as needed; the below check encompasses
@ -1756,6 +1762,15 @@ static void kvm_commit_memory_region(struct kvm *kvm,
if (old->dirty_bitmap && !new->dirty_bitmap)
kvm_destroy_dirty_bitmap(old);
/*
* Unbind the guest_memfd instance as needed; the @new slot has
* already created its own binding. TODO: Drop the WARN when
* dirty logging guest_memfd memslots is supported. Until then,
* flags-only changes on guest_memfd slots should be impossible.
*/
if (WARN_ON_ONCE(old->flags & KVM_MEM_GUEST_MEMFD))
kvm_gmem_unbind(old);
/*
* The final quirk. Free the detached, old slot, but only its
* memory, not any metadata. Metadata, including arch specific