From: jschoenh@amazon.de
Date: Thu, 7 Sep 2017 19:02:30 +0100
Subject: [PATCH 1/2] KVM: VMX: Do not BUG() on out-of-bounds guest IRQ
Git-commit: 3a8b0677fc6180a467e26cc32ce6b0c09a32f9bb
Patch-mainline: v4.14-rc1
References: bsc#1058038, 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, WARN_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).
Signed-off-by: Jan H. Schönherr <jschoenh@amazon.de>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
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
@@ -11370,7 +11370,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) ||
@@ -11379,7 +11379,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])) {
+ WARN_ONCE(1, "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)