53 lines
1.9 KiB
Diff
53 lines
1.9 KiB
Diff
From: =?UTF-8?q?Jan=20H=2E=20Sch=C3=B6nherr?= <jschoenh@amazon.de>
|
|
Date: Thu, 7 Sep 2017 19:02:30 +0100
|
|
Subject: KVM: VMX: Do not BUG() on out-of-bounds guest IRQ
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
Origin: https://git.kernel.org/linus/3a8b0677fc6180a467e26cc32ce6b0c09a32f9bb
|
|
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-1000252
|
|
|
|
The value of the guest_irq argument to vmx_update_pi_irte() is
|
|
ultimately coming from a KVM_IRQFD API call. Do not BUG() in
|
|
vmx_update_pi_irte() if the value is out-of bounds. (Especially,
|
|
since KVM as a whole seems to hang after that.)
|
|
|
|
Instead, print a message only once if we find that we don't have a
|
|
route for a certain IRQ (which can be out-of-bounds or within the
|
|
array).
|
|
|
|
This fixes CVE-2017-1000252.
|
|
|
|
Fixes: efc644048ecde54 ("KVM: x86: Update IRTE for posted-interrupts")
|
|
Signed-off-by: Jan H. Schönherr <jschoenh@amazon.de>
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
---
|
|
arch/x86/kvm/vmx.c | 9 +++++++--
|
|
1 file changed, 7 insertions(+), 2 deletions(-)
|
|
|
|
--- a/arch/x86/kvm/vmx.c
|
|
+++ b/arch/x86/kvm/vmx.c
|
|
@@ -11377,7 +11377,7 @@ static int vmx_update_pi_irte(struct kvm
|
|
struct kvm_lapic_irq irq;
|
|
struct kvm_vcpu *vcpu;
|
|
struct vcpu_data vcpu_info;
|
|
- int idx, ret = -EINVAL;
|
|
+ int idx, ret = 0;
|
|
|
|
if (!kvm_arch_has_assigned_device(kvm) ||
|
|
!irq_remapping_cap(IRQ_POSTING_CAP) ||
|
|
@@ -11386,7 +11386,12 @@ static int vmx_update_pi_irte(struct kvm
|
|
|
|
idx = srcu_read_lock(&kvm->irq_srcu);
|
|
irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
|
|
- BUG_ON(guest_irq >= irq_rt->nr_rt_entries);
|
|
+ if (guest_irq >= irq_rt->nr_rt_entries ||
|
|
+ hlist_empty(&irq_rt->map[guest_irq])) {
|
|
+ pr_warn_once("no route for guest_irq %u/%u (broken user space?)\n",
|
|
+ guest_irq, irq_rt->nr_rt_entries);
|
|
+ goto out;
|
|
+ }
|
|
|
|
hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) {
|
|
if (e->type != KVM_IRQ_ROUTING_MSI)
|