]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.19.7/kvm-arm-arm64-check-irq-number-on-userland-injection.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.19.7 / kvm-arm-arm64-check-irq-number-on-userland-injection.patch
CommitLineData
c9c77b0b
GKH
1From fd1d0ddf2ae92fb3df42ed476939861806c5d785 Mon Sep 17 00:00:00 2001
2From: Andre Przywara <andre.przywara@arm.com>
3Date: Fri, 10 Apr 2015 16:17:59 +0100
4Subject: KVM: arm/arm64: check IRQ number on userland injection
5
6From: Andre Przywara <andre.przywara@arm.com>
7
8commit fd1d0ddf2ae92fb3df42ed476939861806c5d785 upstream.
9
10When userland injects a SPI via the KVM_IRQ_LINE ioctl we currently
11only check it against a fixed limit, which historically is set
12to 127. With the new dynamic IRQ allocation the effective limit may
13actually be smaller (64).
14So when now a malicious or buggy userland injects a SPI in that
15range, we spill over on our VGIC bitmaps and bytemaps memory.
16I could trigger a host kernel NULL pointer dereference with current
17mainline by injecting some bogus IRQ number from a hacked kvmtool:
18-----------------
19....
20DEBUG: kvm_vgic_inject_irq(kvm, cpu=0, irq=114, level=1)
21DEBUG: vgic_update_irq_pending(kvm, cpu=0, irq=114, level=1)
22DEBUG: IRQ #114 still in the game, writing to bytemap now...
23Unable to handle kernel NULL pointer dereference at virtual address 00000000
24pgd = ffffffc07652e000
25[00000000] *pgd=00000000f658b003, *pud=00000000f658b003, *pmd=0000000000000000
26Internal error: Oops: 96000006 [#1] PREEMPT SMP
27Modules linked in:
28CPU: 1 PID: 1053 Comm: lkvm-msi-irqinj Not tainted 4.0.0-rc7+ #3027
29Hardware name: FVP Base (DT)
30task: ffffffc0774e9680 ti: ffffffc0765a8000 task.ti: ffffffc0765a8000
31PC is at kvm_vgic_inject_irq+0x234/0x310
32LR is at kvm_vgic_inject_irq+0x30c/0x310
33pc : [<ffffffc0000ae0a8>] lr : [<ffffffc0000ae180>] pstate: 80000145
34.....
35
36So this patch fixes this by checking the SPI number against the
37actual limit. Also we remove the former legacy hard limit of
38127 in the ioctl code.
39
40Signed-off-by: Andre Przywara <andre.przywara@arm.com>
41Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
42[maz: wrap KVM_ARM_IRQ_GIC_MAX with #ifndef __KERNEL__,
43as suggested by Christopher Covington]
44Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
45Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
46
47---
48 arch/arm/include/uapi/asm/kvm.h | 8 +++++++-
49 arch/arm/kvm/arm.c | 3 +--
50 arch/arm64/include/uapi/asm/kvm.h | 8 +++++++-
51 virt/kvm/arm/vgic.c | 3 +++
52 4 files changed, 18 insertions(+), 4 deletions(-)
53
54--- a/arch/arm/include/uapi/asm/kvm.h
55+++ b/arch/arm/include/uapi/asm/kvm.h
56@@ -193,8 +193,14 @@ struct kvm_arch_memory_slot {
57 #define KVM_ARM_IRQ_CPU_IRQ 0
58 #define KVM_ARM_IRQ_CPU_FIQ 1
59
60-/* Highest supported SPI, from VGIC_NR_IRQS */
61+/*
62+ * This used to hold the highest supported SPI, but it is now obsolete
63+ * and only here to provide source code level compatibility with older
64+ * userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS.
65+ */
66+#ifndef __KERNEL__
67 #define KVM_ARM_IRQ_GIC_MAX 127
68+#endif
69
70 /* PSCI interface */
71 #define KVM_PSCI_FN_BASE 0x95c1ba5e
72--- a/arch/arm/kvm/arm.c
73+++ b/arch/arm/kvm/arm.c
74@@ -644,8 +644,7 @@ int kvm_vm_ioctl_irq_line(struct kvm *kv
75 if (!irqchip_in_kernel(kvm))
76 return -ENXIO;
77
78- if (irq_num < VGIC_NR_PRIVATE_IRQS ||
79- irq_num > KVM_ARM_IRQ_GIC_MAX)
80+ if (irq_num < VGIC_NR_PRIVATE_IRQS)
81 return -EINVAL;
82
83 return kvm_vgic_inject_irq(kvm, 0, irq_num, level);
84--- a/arch/arm64/include/uapi/asm/kvm.h
85+++ b/arch/arm64/include/uapi/asm/kvm.h
86@@ -179,8 +179,14 @@ struct kvm_arch_memory_slot {
87 #define KVM_ARM_IRQ_CPU_IRQ 0
88 #define KVM_ARM_IRQ_CPU_FIQ 1
89
90-/* Highest supported SPI, from VGIC_NR_IRQS */
91+/*
92+ * This used to hold the highest supported SPI, but it is now obsolete
93+ * and only here to provide source code level compatibility with older
94+ * userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS.
95+ */
96+#ifndef __KERNEL__
97 #define KVM_ARM_IRQ_GIC_MAX 127
98+#endif
99
100 /* PSCI interface */
101 #define KVM_PSCI_FN_BASE 0x95c1ba5e
102--- a/virt/kvm/arm/vgic.c
103+++ b/virt/kvm/arm/vgic.c
104@@ -1706,6 +1706,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm,
105 goto out;
106 }
107
108+ if (irq_num >= kvm->arch.vgic.nr_irqs)
109+ return -EINVAL;
110+
111 vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
112 if (vcpu_id >= 0) {
113 /* kick the specified vcpu */