[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CANhq1J6AJvkXUVZtbYgZubepU8xL88Q56UrcDprmG_eDapmXtA@mail.gmail.com>
Date: Fri, 17 Apr 2020 21:24:10 +0800
From: sam hao <ssesamhao@...il.com>
To: kvm@...r.kernel.org, linux-kernel@...r.kernel.org,
pbonzini@...hat.com
Subject: Slab-of-out-bounds in search_memslots() in kvm_host.h
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
Powered by blists - more mailing lists