lkml.org 
[lkml]   [2020]   [Apr]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 113/167] KVM: Check validity of resolved slot when searching memslots
    Date
    From: Sean Christopherson <sean.j.christopherson@intel.com>

    commit b6467ab142b708dd076f6186ca274f14af379c72 upstream.

    Check that the resolved slot (somewhat confusingly named 'start') is a
    valid/allocated slot before doing the final comparison to see if the
    specified gfn resides in the associated slot. The resolved slot can be
    invalid if the binary search loop terminated because the search index
    was incremented beyond the number of used slots.

    This bug has existed since the binary search algorithm was introduced,
    but went unnoticed because KVM statically allocated memory for the max
    number of slots, i.e. the access would only be truly out-of-bounds if
    all possible slots were allocated and the specified gfn was less than
    the base of the lowest memslot. Commit 36947254e5f98 ("KVM: Dynamically
    size memslot array based on number of used slots") eliminated the "all
    possible slots allocated" condition and made the bug embarrasingly easy
    to hit.

    Fixes: 9c1a5d38780e6 ("kvm: optimize GFN to memslot lookup with large slots amount")
    Reported-by: syzbot+d889b59b2bb87d4047a2@syzkaller.appspotmail.com
    Cc: stable@vger.kernel.org
    Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
    Message-Id: <20200408064059.8957-2-sean.j.christopherson@intel.com>
    Reviewed-by: Cornelia Huck <cohuck@redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    include/linux/kvm_host.h | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    --- a/include/linux/kvm_host.h
    +++ b/include/linux/kvm_host.h
    @@ -1039,7 +1039,7 @@ search_memslots(struct kvm_memslots *slo
    start = slot + 1;
    }

    - if (gfn >= memslots[start].base_gfn &&
    + if (start < slots->used_slots && gfn >= memslots[start].base_gfn &&
    gfn < memslots[start].base_gfn + memslots[start].npages) {
    atomic_set(&slots->lru_slot, start);
    return &memslots[start];

    \
     
     \ /
      Last update: 2020-04-28 20:55    [W:4.109 / U:0.264 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site