KVM: validate userspace input in kvm_clear_dirty_log_protect()
authorTomas Bortoli <tomasbortoli@gmail.com>
Wed, 2 Jan 2019 17:29:37 +0000 (18:29 +0100)
committerRadim Krčmář <rkrcmar@redhat.com>
Fri, 11 Jan 2019 17:38:07 +0000 (18:38 +0100)
The function at issue does not fully validate the content of the
structure pointed by the log parameter, though its content has just been
copied from userspace and lacks validation. Fix that.

Moreover, change the type of n to unsigned long as that is the type
returned by kvm_dirty_bitmap_bytes().

Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com>
Reported-by: syzbot+028366e52c9ace67deb3@syzkaller.appspotmail.com
[Squashed the fix from Paolo. - Radim.]
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
virt/kvm/kvm_main.c

index 1f888a103f78841267f3ca032f83381ed0eeff0d..5ecea812cb6a24056ee5ab42aa585cb7f5ce15ab 100644 (file)
@@ -1227,9 +1227,9 @@ int kvm_clear_dirty_log_protect(struct kvm *kvm,
 {
        struct kvm_memslots *slots;
        struct kvm_memory_slot *memslot;
-       int as_id, id, n;
+       int as_id, id;
        gfn_t offset;
-       unsigned long i;
+       unsigned long i, n;
        unsigned long *dirty_bitmap;
        unsigned long *dirty_bitmap_buffer;
 
@@ -1249,6 +1249,11 @@ int kvm_clear_dirty_log_protect(struct kvm *kvm,
                return -ENOENT;
 
        n = kvm_dirty_bitmap_bytes(memslot);
+
+       if (log->first_page > memslot->npages ||
+           log->num_pages > memslot->npages - log->first_page)
+                       return -EINVAL;
+
        *flush = false;
        dirty_bitmap_buffer = kvm_second_dirty_bitmap(memslot);
        if (copy_from_user(dirty_bitmap_buffer, log->dirty_bitmap, n))