diff options
| author | Radim Krčmář <rkrcmar@redhat.com> | 2016-11-23 15:15:27 -0500 |
|---|---|---|
| committer | Radim Krčmář <rkrcmar@redhat.com> | 2016-11-24 12:37:19 -0500 |
| commit | 81cdb259fb6d8c1c4ecfeea389ff5a73c07f5755 (patch) | |
| tree | c0e087707bb37d045abc32dce1888afcfa4c977d | |
| parent | 2117d5398c81554fbf803f5fd1dc55eb78216c0c (diff) | |
KVM: x86: fix out-of-bounds accesses of rtc_eoi map
KVM was using arrays of size KVM_MAX_VCPUS with vcpu_id, but ID can be
bigger that the maximal number of VCPUs, resulting in out-of-bounds
access.
Found by syzkaller:
BUG: KASAN: slab-out-of-bounds in __apic_accept_irq+0xb33/0xb50 at addr [...]
Write of size 1 by task a.out/27101
CPU: 1 PID: 27101 Comm: a.out Not tainted 4.9.0-rc5+ #49
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
[...]
Call Trace:
[...] __apic_accept_irq+0xb33/0xb50 arch/x86/kvm/lapic.c:905
[...] kvm_apic_set_irq+0x10e/0x180 arch/x86/kvm/lapic.c:495
[...] kvm_irq_delivery_to_apic+0x732/0xc10 arch/x86/kvm/irq_comm.c:86
[...] ioapic_service+0x41d/0x760 arch/x86/kvm/ioapic.c:360
[...] ioapic_set_irq+0x275/0x6c0 arch/x86/kvm/ioapic.c:222
[...] kvm_ioapic_inject_all arch/x86/kvm/ioapic.c:235
[...] kvm_set_ioapic+0x223/0x310 arch/x86/kvm/ioapic.c:670
[...] kvm_vm_ioctl_set_irqchip arch/x86/kvm/x86.c:3668
[...] kvm_arch_vm_ioctl+0x1a08/0x23c0 arch/x86/kvm/x86.c:3999
[...] kvm_vm_ioctl+0x1fa/0x1a70 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3099
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: stable@vger.kernel.org
Fixes: af1bae5497b9 ("KVM: x86: bump KVM_MAX_VCPU_ID to 1023")
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
| -rw-r--r-- | arch/x86/kvm/ioapic.c | 2 | ||||
| -rw-r--r-- | arch/x86/kvm/ioapic.h | 4 |
2 files changed, 3 insertions, 3 deletions
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index 1a22de70f7f7..6e219e5c07d2 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c | |||
| @@ -94,7 +94,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, | |||
| 94 | static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) | 94 | static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) |
| 95 | { | 95 | { |
| 96 | ioapic->rtc_status.pending_eoi = 0; | 96 | ioapic->rtc_status.pending_eoi = 0; |
| 97 | bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPUS); | 97 | bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); | 100 | static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); |
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h index 7d2692a49657..1cc6e54436db 100644 --- a/arch/x86/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h | |||
| @@ -42,13 +42,13 @@ struct kvm_vcpu; | |||
| 42 | 42 | ||
| 43 | struct dest_map { | 43 | struct dest_map { |
| 44 | /* vcpu bitmap where IRQ has been sent */ | 44 | /* vcpu bitmap where IRQ has been sent */ |
| 45 | DECLARE_BITMAP(map, KVM_MAX_VCPUS); | 45 | DECLARE_BITMAP(map, KVM_MAX_VCPU_ID); |
| 46 | 46 | ||
| 47 | /* | 47 | /* |
| 48 | * Vector sent to a given vcpu, only valid when | 48 | * Vector sent to a given vcpu, only valid when |
| 49 | * the vcpu's bit in map is set | 49 | * the vcpu's bit in map is set |
| 50 | */ | 50 | */ |
| 51 | u8 vectors[KVM_MAX_VCPUS]; | 51 | u8 vectors[KVM_MAX_VCPU_ID]; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | 54 | ||
