Skip to content

Commit ed8f966

Browse files
sean-jcbonzini
authored andcommitted
KVM: Assert that a destroyed/freed vCPU is no longer visible
After freeing a vCPU, assert that it is no longer reachable, and that kvm_get_vcpu() doesn't return garbage or a pointer to some other vCPU. While KVM obviously shouldn't be attempting to access a freed vCPU, it's all too easy for KVM to make a VM-wide request, e.g. via KVM_BUG_ON() or kvm_flush_remote_tlbs(). Alternatively, KVM could short-circuit problematic paths if the VM's refcount has gone to zero, e.g. in kvm_make_all_cpus_request(), or KVM could try disallow making global requests during teardown. But given that deleting the vCPU from the array Just Works, adding logic to the requests path is unnecessary, and trying to make requests illegal during teardown would be a fool's errand. Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20250224235542.2562848-4-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent ed09b50 commit ed8f966

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

virt/kvm/kvm_main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,14 @@ void kvm_destroy_vcpus(struct kvm *kvm)
489489
kvm_for_each_vcpu(i, vcpu, kvm) {
490490
kvm_vcpu_destroy(vcpu);
491491
xa_erase(&kvm->vcpu_array, i);
492+
493+
/*
494+
* Assert that the vCPU isn't visible in any way, to ensure KVM
495+
* doesn't trigger a use-after-free if destroying vCPUs results
496+
* in VM-wide request, e.g. to flush remote TLBs when tearing
497+
* down MMUs, or to mark the VM dead if a KVM_BUG_ON() fires.
498+
*/
499+
WARN_ON_ONCE(xa_load(&kvm->vcpu_array, i) || kvm_get_vcpu(kvm, i));
492500
}
493501

494502
atomic_set(&kvm->online_vcpus, 0);

0 commit comments

Comments
 (0)