diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-06-01 14:09:21 +0200 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2016-08-22 22:38:08 +0100 |
commit | 45ebfe5310371818aa1e65f31ea487e9217889fd (patch) | |
tree | dba5c7a9b26b23eea1ae08fa338962b962018c25 | |
parent | eb4518af956cd7ab0cea569474d2546b9a9a9643 (diff) | |
download | linux-stable-45ebfe5310371818aa1e65f31ea487e9217889fd.tar.gz linux-stable-45ebfe5310371818aa1e65f31ea487e9217889fd.tar.bz2 linux-stable-45ebfe5310371818aa1e65f31ea487e9217889fd.zip |
KVM: irqfd: fix NULL pointer dereference in kvm_irq_map_gsi
commit c622a3c21ede892e370b56e1ceb9eb28f8bbda6b upstream.
Found by syzkaller:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000120
IP: [<ffffffffa0797202>] kvm_irq_map_gsi+0x12/0x90 [kvm]
PGD 6f80b067 PUD b6535067 PMD 0
Oops: 0000 [#1] SMP
CPU: 3 PID: 4988 Comm: a.out Not tainted 4.4.9-300.fc23.x86_64 #1
[...]
Call Trace:
[<ffffffffa0795f62>] irqfd_update+0x32/0xc0 [kvm]
[<ffffffffa0796c7c>] kvm_irqfd+0x3dc/0x5b0 [kvm]
[<ffffffffa07943f4>] kvm_vm_ioctl+0x164/0x6f0 [kvm]
[<ffffffff81241648>] do_vfs_ioctl+0x298/0x480
[<ffffffff812418a9>] SyS_ioctl+0x79/0x90
[<ffffffff817a1062>] tracesys_phase2+0x84/0x89
Code: b5 71 a7 e0 5b 41 5c 41 5d 5d f3 c3 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 8b 8f 10 2e 00 00 31 c0 48 89 e5 <39> 91 20 01 00 00 76 6a 48 63 d2 48 8b 94 d1 28 01 00 00 48 85
RIP [<ffffffffa0797202>] kvm_irq_map_gsi+0x12/0x90 [kvm]
RSP <ffff8800926cbca8>
CR2: 0000000000000120
Testcase:
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdint.h>
#include <linux/kvm.h>
#include <fcntl.h>
#include <sys/ioctl.h>
long r[26];
int main()
{
memset(r, -1, sizeof(r));
r[2] = open("/dev/kvm", 0);
r[3] = ioctl(r[2], KVM_CREATE_VM, 0);
struct kvm_irqfd ifd;
ifd.fd = syscall(SYS_eventfd2, 5, 0);
ifd.gsi = 3;
ifd.flags = 2;
ifd.resamplefd = ifd.fd;
r[25] = ioctl(r[3], KVM_IRQFD, &ifd);
return 0;
}
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r-- | virt/kvm/irqchip.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index b43c275775cd..2a1f6a0a0dff 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -127,7 +127,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, */ idx = srcu_read_lock(&kvm->irq_srcu); irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); - if (irq < irq_rt->nr_rt_entries) + if (irq_rt && irq < irq_rt->nr_rt_entries) hlist_for_each_entry(e, &irq_rt->map[irq], link) irq_set[i++] = *e; srcu_read_unlock(&kvm->irq_srcu, idx); |