lkml.org 
[lkml]   [2022]   [Aug]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH 1/3] KVM: Properly unwind VM creation if creating debugfs fails
    From
    Properly unwind VM creation if kvm_create_vm_debugfs() fails.  A recent
    change to invoke kvm_create_vm_debug() in kvm_create_vm() was led astray
    by buggy try_get_module() handling adding by commit 5f6de5cbebee ("KVM:
    Prevent module exit until all VMs are freed"). The debugfs error path
    effectively inherits the bad error path of try_module_get(), e.g. KVM
    leaves the to-be-free VM on vm_list even though KVM appears to do the
    right thing by calling module_put() and falling through.

    Opportunistically hoist kvm_create_vm_debugfs() above the call to
    kvm_arch_post_init_vm() so that the "post-init" arch hook is actually
    invoked after the VM is initialized (ignoring kvm_coalesced_mmio_init()
    for the moment). x86 is the only non-nop implementation of the post-init
    hook, and it doesn't allocate/initialize any objects that are reachable
    via debugfs code (spawns a kthread worker for the NX huge page mitigation).

    Leave the buggy try_get_module() alone for now, it will be fixed in a
    separate commit.

    Fixes: b74ed7a68ec1 ("KVM: Actually create debugfs in kvm_create_vm()")
    Reported-by: syzbot+744e173caec2e1627ee0@syzkaller.appspotmail.com
    Cc: Oliver Upton <oliver.upton@linux.dev>
    Signed-off-by: Sean Christopherson <seanjc@google.com>
    ---
    virt/kvm/kvm_main.c | 16 ++++++++--------
    1 file changed, 8 insertions(+), 8 deletions(-)

    diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
    index 515dfe9d3bcf..ee5f48cc100b 100644
    --- a/virt/kvm/kvm_main.c
    +++ b/virt/kvm/kvm_main.c
    @@ -1211,9 +1211,13 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
    if (r)
    goto out_err_no_mmu_notifier;

    + r = kvm_create_vm_debugfs(kvm, fdname);
    + if (r)
    + goto out_err_no_debugfs;
    +
    r = kvm_arch_post_init_vm(kvm);
    if (r)
    - goto out_err_mmu_notifier;
    + goto out_err;

    mutex_lock(&kvm_lock);
    list_add(&kvm->vm_list, &vm_list);
    @@ -1229,18 +1233,14 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
    */
    if (!try_module_get(kvm_chardev_ops.owner)) {
    r = -ENODEV;
    - goto out_err_mmu_notifier;
    - }
    -
    - r = kvm_create_vm_debugfs(kvm, fdname);
    - if (r)
    goto out_err;
    + }

    return kvm;

    out_err:
    - module_put(kvm_chardev_ops.owner);
    -out_err_mmu_notifier:
    + kvm_destroy_vm_debugfs(kvm);
    +out_err_no_debugfs:
    #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
    if (kvm->mmu_notifier.ops)
    mmu_notifier_unregister(&kvm->mmu_notifier, current->mm);
    --
    2.37.1.595.g718a3a8f04-goog
    \
     
     \ /
      Last update: 2022-08-16 10:32    [W:2.776 / U:0.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site