linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Slab-of-out-bounds in search_memslots() in kvm_host.h
@ 2020-04-17 13:24 sam hao
  2020-04-17 14:48 ` Sean Christopherson
  0 siblings, 1 reply; 2+ messages in thread
From: sam hao @ 2020-04-17 13:24 UTC (permalink / raw)
  To: kvm, linux-kernel, pbonzini

Hi,

I've found possible out of bounds access in search_memslots() in kvm_host.h.
In search_memslots(struct kvm_memslots *slots, gfn_t gfn),  a binary
search is used  for slot searching,  as following code shows
        while (start < end) {
                slot = start + (end - start) / 2;

                if (gfn >= memslots[slot].base_gfn)
                        end = slot;
                else
                        start = slot + 1;
        }

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

However, start may equal to slots->used_slots  when gfn is smaller
than every base_gfn, which cause out of bound access in  if condition.
Following code can trigger this bug:

#include <stdint.h>
#include <unistd.h>
#include <linux/kvm.h>
#include <asm/kvm.h>
#include <sys/ioctl.h>
#include <fcntl.h>

int main(int argc, char **agrv){

        struct kvm_userspace_memory_region kvm_userspace_memory_region_0 = {
                .slot = 4098152658,
                .flags = 1653871800,
                .guest_phys_addr = 9228163640593578308,
                .memory_size = 13154652985641659684,
                .userspace_addr = 2934507574655831761
        };
        char *s_0 = "/dev/kvm";
        struct kvm_vapic_addr kvm_vapic_addr_1 = {
                .vapic_addr=4096
        };

        int32_t r0 = open(s_0,0,0);
        int32_t r1 = ioctl(r0,44545,0);
        ioctl(r1,44640);
        ioctl(r1,1075883590,&kvm_userspace_memory_region_0);
        int32_t r2 = ioctl(r1,44609,0);
        ioctl(r2,44672,0);
        ioctl(r2,1074310803,&kvm_vapic_addr_1);
        return 0;
}

Consider adding a bound-check in if-condition as following code :

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];
}

-- 
Hao Sun

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Slab-of-out-bounds in search_memslots() in kvm_host.h
  2020-04-17 13:24 Slab-of-out-bounds in search_memslots() in kvm_host.h sam hao
@ 2020-04-17 14:48 ` Sean Christopherson
  0 siblings, 0 replies; 2+ messages in thread
From: Sean Christopherson @ 2020-04-17 14:48 UTC (permalink / raw)
  To: sam hao; +Cc: kvm, linux-kernel, pbonzini

On Fri, Apr 17, 2020 at 09:24:10PM +0800, sam hao wrote:
> Hi,
> 
> I've found possible out of bounds access in search_memslots() in kvm_host.h.

...

> 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];
> }

Fixed (with this exact check) by commit b6467ab142b7 ("KVM: Check validity
of resolved slot when searching memslots").  Syzbot found this one very
quickly :-)  Thanks!

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-04-17 14:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-17 13:24 Slab-of-out-bounds in search_memslots() in kvm_host.h sam hao
2020-04-17 14:48 ` Sean Christopherson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).