aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorTomas Bortoli <tomasbortoli@gmail.com>2019-01-02 12:29:37 -0500
committerRadim Krčmář <rkrcmar@redhat.com>2019-01-11 12:38:07 -0500
commit98938aa8edd66dc95024d7c936a4bc315f6615ff (patch)
treebd375434926fae25fdef397e84d24d39bf891eeb /virt
parentd14eff1bc53e6a268c3b48da5cdb469f26832d1a (diff)
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>
Diffstat (limited to 'virt')
-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,
1227{ 1227{
1228 struct kvm_memslots *slots; 1228 struct kvm_memslots *slots;
1229 struct kvm_memory_slot *memslot; 1229 struct kvm_memory_slot *memslot;
1230 int as_id, id, n; 1230 int as_id, id;
1231 gfn_t offset; 1231 gfn_t offset;
1232 unsigned long i; 1232 unsigned long i, n;
1233 unsigned long *dirty_bitmap; 1233 unsigned long *dirty_bitmap;
1234 unsigned long *dirty_bitmap_buffer; 1234 unsigned long *dirty_bitmap_buffer;
1235 1235
@@ -1249,6 +1249,11 @@ int kvm_clear_dirty_log_protect(struct kvm *kvm,
1249 return -ENOENT; 1249 return -ENOENT;
1250 1250
1251 n = kvm_dirty_bitmap_bytes(memslot); 1251 n = kvm_dirty_bitmap_bytes(memslot);
1252
1253 if (log->first_page > memslot->npages ||
1254 log->num_pages > memslot->npages - log->first_page)
1255 return -EINVAL;
1256
1252 *flush = false; 1257 *flush = false;
1253 dirty_bitmap_buffer = kvm_second_dirty_bitmap(memslot); 1258 dirty_bitmap_buffer = kvm_second_dirty_bitmap(memslot);
1254 if (copy_from_user(dirty_bitmap_buffer, log->dirty_bitmap, n)) 1259 if (copy_from_user(dirty_bitmap_buffer, log->dirty_bitmap, n))