lkml.org 
[lkml]   [2020]   [Mar]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/6] KVM: nVMX: avoid NULL pointer dereference with incorrect EVMCS GPAs
    Date
    When an EVMCS enabled L1 guest on KVM will tries doing enlightened VMEnter
    with EVMCS GPA = 0 the host crashes because the

    evmcs_gpa != vmx->nested.hv_evmcs_vmptr

    condition in nested_vmx_handle_enlightened_vmptrld() will evaluate to
    false (as nested.hv_evmcs_vmptr is zeroed after init). The crash will
    happen on vmx->nested.hv_evmcs pointer dereference.

    Another problematic EVMCS ptr value is '-1' but it only causes host crash
    after nested_release_evmcs() invocation. The problem is exactly the same as
    with '0', we mistakenly think that the EVMCS pointer hasn't changed and
    thus nested.hv_evmcs_vmptr is valid.

    Resolve the issue by adding an additional !vmx->nested.hv_evmcs
    check to nested_vmx_handle_enlightened_vmptrld(), this way we will
    always be trying kvm_vcpu_map() when nested.hv_evmcs is NULL
    and this is supposed to catch all invalid EVMCS GPAs.

    Also, initialize hv_evmcs_vmptr to '0' in nested_release_evmcs()
    to be consistent with initialization where we don't currently
    set hv_evmcs_vmptr to '-1'.

    Cc: stable@vger.kernel.org
    Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
    ---
    arch/x86/kvm/vmx/nested.c | 5 +++--
    1 file changed, 3 insertions(+), 2 deletions(-)

    diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
    index e920d7834d73..9750e590c89d 100644
    --- a/arch/x86/kvm/vmx/nested.c
    +++ b/arch/x86/kvm/vmx/nested.c
    @@ -224,7 +224,7 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu)
    return;

    kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true);
    - vmx->nested.hv_evmcs_vmptr = -1ull;
    + vmx->nested.hv_evmcs_vmptr = 0;
    vmx->nested.hv_evmcs = NULL;
    }

    @@ -1923,7 +1923,8 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu,
    if (!nested_enlightened_vmentry(vcpu, &evmcs_gpa))
    return 1;

    - if (unlikely(evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) {
    + if (unlikely(!vmx->nested.hv_evmcs ||
    + evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) {
    if (!vmx->nested.hv_evmcs)
    vmx->nested.current_vmptr = -1ull;

    --
    2.24.1
    \
     
     \ /
      Last update: 2020-03-09 16:52    [W:4.535 / U:0.304 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site