Skip to content
  • Wanpeng Li's avatar
    KVM: VMX: Fix vmx->nested freeing when no SMI handler · b7455825
    Wanpeng Li authored
    Reported by syzkaller:
    
       ------------[ cut here ]------------
       WARNING: CPU: 5 PID: 2939 at arch/x86/kvm/vmx.c:3844 free_loaded_vmcs+0x77/0x80 [kvm_intel]
       CPU: 5 PID: 2939 Comm: repro Not tainted 4.14.0+ #26
       RIP: 0010:free_loaded_vmcs+0x77/0x80 [kvm_intel]
       Call Trace:
        vmx_free_vcpu+0xda/0x130 [kvm_intel]
        kvm_arch_destroy_vm+0x192/0x290 [kvm]
        kvm_put_kvm+0x262/0x560 [kvm]
        kvm_vm_release+0x2c/0x30 [kvm]
        __fput+0x190/0x370
        task_work_run+0xa1/0xd0
        do_exit+0x4d2/0x13e0
        do_group_exit+0x89/0x140
        get_signal+0x318/0xb80
        do_signal+0x8c/0xb40
        exit_to_usermode_loop+0xe4/0x140
        syscall_return_slowpath+0x206/0x230
        entry_SYSCALL_64_fastpath+0x98/0x9a
    
    The syzkaller testcase will execute VMXON/VMLAUCH instructions, so the
    vmx->nested stuff is populated, it will also issue KVM_SMI ioctl. However,
    the testcase is just a simple c program and not be lauched by something
    like seabios which implements smi_handler. Commit 05cade71
    
     (KVM: nSVM:
    fix SMI injection in guest mode) gets out of guest mode and set nested.vmxon
    to false for the duration of SMM according to SDM 34.14.1 "leave VMX
    operation" upon entering SMM. We can't alloc/free the vmx->nested stuff
    each time when entering/exiting SMM since it will induce more overhead. So
    the function vmx_pre_enter_smm() marks nested.vmxon false even if vmx->nested
    stuff is still populated. What it expected is em_rsm() can mark nested.vmxon
    to be true again. However, the smi_handler/rsm will not execute since there
    is no something like seabios in this scenario. The function free_nested()
    fails to free the vmx->nested stuff since the vmx->nested.vmxon is false
    which results in the above warning.
    
    This patch fixes it by also considering the no SMI handler case, luckily
    vmx->nested.smm.vmxon is marked according to the value of vmx->nested.vmxon
    in vmx_pre_enter_smm(), we can take advantage of it and free vmx->nested
    stuff when L1 goes down.
    
    Reported-by: default avatarDmitry Vyukov <dvyukov@google.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Radim Krčmář <rkrcmar@redhat.com>
    Cc: Dmitry Vyukov <dvyukov@google.com>
    Reviewed-by: default avatarLiran Alon <liran.alon@oracle.com>
    Fixes: 05cade71
    
     (KVM: nSVM: fix SMI injection in guest mode)
    Signed-off-by: default avatarWanpeng Li <wanpeng.li@hotmail.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    b7455825