summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bortoli <tomasbortoli@gmail.com>2019-01-02 20:29:37 +0300
committerRadim Krčmář <rkrcmar@redhat.com>2019-01-11 20:38:07 +0300
commit98938aa8edd66dc95024d7c936a4bc315f6615ff (patch)
treebd375434926fae25fdef397e84d24d39bf891eeb
parentd14eff1bc53e6a268c3b48da5cdb469f26832d1a (diff)
downloadlinux-98938aa8edd66dc95024d7c936a4bc315f6615ff.tar.xz
KVM: validate userspace input in kvm_clear_dirty_log_protect()
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>
-rw-r--r--virt/kvm/kvm_main.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 1f888a103f78..5ecea812cb6a 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -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))