summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-12-17 09:36:19 -0800
committerPaolo Bonzini <pbonzini@redhat.com>2018-12-18 22:07:25 +0100
commit987d1149be7ddcc1380ff946cf236874421a7e1b (patch)
tree9be3c66bbd4dbee557e1372874b6b913535c73cc /virt
parent7566ec393f4161572ba6f11ad5171fd5d59b0fbd (diff)
downloadlinux-987d1149be7ddcc1380ff946cf236874421a7e1b.tar.bz2
KVM: fix unregistering coalesced mmio zone from wrong bus
If you register a kvm_coalesced_mmio_zone with '.pio = 0' but then unregister it with '.pio = 1', KVM_UNREGISTER_COALESCED_MMIO will try to unregister it from KVM_PIO_BUS rather than KVM_MMIO_BUS, which is a no-op. But it frees the kvm_coalesced_mmio_dev anyway, causing a use-after-free. Fix it by only unregistering and freeing the zone if the correct value of 'pio' is provided. Reported-by: syzbot+f87f60bb6f13f39b54e3@syzkaller.appspotmail.com Fixes: 0804c849f1df ("kvm/x86 : add coalesced pio support") Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/coalesced_mmio.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index 3710342cf6ad..6855cce3e528 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -175,10 +175,14 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
{
struct kvm_coalesced_mmio_dev *dev, *tmp;
+ if (zone->pio != 1 && zone->pio != 0)
+ return -EINVAL;
+
mutex_lock(&kvm->slots_lock);
list_for_each_entry_safe(dev, tmp, &kvm->coalesced_zones, list)
- if (coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
+ if (zone->pio == dev->zone.pio &&
+ coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
kvm_io_bus_unregister_dev(kvm,
zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev);
kvm_iodevice_destructor(&dev->dev);