summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-12-17 12:36:19 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2018-12-18 16:07:25 -0500
commit987d1149be7ddcc1380ff946cf236874421a7e1b (patch)
tree9be3c66bbd4dbee557e1372874b6b913535c73cc
parent7566ec393f4161572ba6f11ad5171fd5d59b0fbd (diff)
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>
-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,
175{ 175{
176 struct kvm_coalesced_mmio_dev *dev, *tmp; 176 struct kvm_coalesced_mmio_dev *dev, *tmp;
177 177
178 if (zone->pio != 1 && zone->pio != 0)
179 return -EINVAL;
180
178 mutex_lock(&kvm->slots_lock); 181 mutex_lock(&kvm->slots_lock);
179 182
180 list_for_each_entry_safe(dev, tmp, &kvm->coalesced_zones, list) 183 list_for_each_entry_safe(dev, tmp, &kvm->coalesced_zones, list)
181 if (coalesced_mmio_in_range(dev, zone->addr, zone->size)) { 184 if (zone->pio == dev->zone.pio &&
185 coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
182 kvm_io_bus_unregister_dev(kvm, 186 kvm_io_bus_unregister_dev(kvm,
183 zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev); 187 zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev);
184 kvm_iodevice_destructor(&dev->dev); 188 kvm_iodevice_destructor(&dev->dev);