Patch "KVM: arm/arm64: check IRQ number on userland injection" has been added to the 4.0-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
KVM: arm/arm64: check IRQ number on userland injection
to the 4.0-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-arm-arm64-check-irq-number-on-userland-injection.patch
and it can be found in the queue-4.0 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
fd1d0ddf2ae92fb3df42ed476939861806c5d785Mon Sep 17 00:00:00 2001
From: Andre Przywara <[email protected]>
Date: Fri, 10 Apr 2015 16:17:59 +0100
Subject: KVM: arm/arm64: check IRQ number on userland injection
From: Andre Przywara <[email protected]>
commit fd1d0ddf2ae92fb3df42ed476939861806c5d785 upstream.
When userland injects a SPI via the KVM_IRQ_LINE ioctl we currently only check it against a fixed limit, which historically is set to 127. With the new dynamic IRQ allocation the effective limit may actually be smaller (64).
So when now a malicious or buggy userland injects a SPI in that range, we spill over on our VGIC bitmaps and bytemaps memory. I could trigger a host kernel NULL pointer dereference with current mainline by injecting some bogus IRQ number from a hacked kvmtool:
-----------------
....
DEBUG: kvm_vgic_inject_irq(kvm, cpu=0, irq=114, level=1)
DEBUG: vgic_update_irq_pending(kvm, cpu=0, irq=114, level=1)
DEBUG: IRQ #114 still in the game, writing to bytemap now...
Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = ffffffc07652e000 [00000000] *pgd=00000000f658b003, *pud=00000000f658b003, *pmd=0000000000000000 Internal error: Oops: 96000006 [#1] PREEMPT SMP Modules linked in: CPU: 1 PID: 1053 Comm: lkvm-msi-irqinj Not tainted 4.0.0-rc7+ #3027 Hardware name: FVP Base (DT) task: ffffffc0774e9680 ti: ffffffc0765a8000 task.ti: ffffffc0765a8000 PC is at kvm_vgic_inject_irq+0x234/0x310 LR is at kvm_vgic_inject_irq+0x30c/0x310 pc : [<ffffffc0000ae0a8>] lr : [<ffffffc0000ae180>] pstate: 80000145
.....
So this patch fixes this by checking the SPI number against the actual limit. Also we remove the former legacy hard limit of 127 in the ioctl code.
[maz: wrap KVM_ARM_IRQ_GIC_MAX with #ifndef __KERNEL__, as suggested by Christopher Covington]
--- arch/arm/include/uapi/asm/kvm.h | 8 +++++++- arch/arm/kvm/arm.c | 3 +-- arch/arm64/include/uapi/asm/kvm.h | 8 +++++++- virt/kvm/arm/vgic.c | 3 +++ 4 files changed, 18 insertions(+), 4 deletions(-)
arch/arm/include/uapi/asm/kvm.h +7 -1
@@ -195,8 +195,14 @@ struct kvm_arch_memory_slot {#define KVM_ARM_IRQ_CPU_IRQ 0#define KVM_ARM_IRQ_CPU_FIQ 1 -/* Highest supported SPI, from VGIC_NR_IRQS */ +/* +* This used to hold the highest supported SPI, but it is now obsolete +* and only here to provide source code level compatibility with older +* userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS. +*/ +#ifndef __KERNEL__#define KVM_ARM_IRQ_GIC_MAX 127 +#endif /* PSCI interface */ #define KVM_PSCI_FN_BASE 0x95c1ba5e
arch/arm/kvm/arm.c +1 -2
@@ -651,8 +651,7 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvif (!irqchip_in_kernel (kvm))return -ENXIO ; -if (irq_num <VGIC_NR_PRIVATE_IRQS || - irq_num >KVM_ARM_IRQ_GIC_MAX ) +if (irq_num <VGIC_NR_PRIVATE_IRQS )return -EINVAL ;return kvm_vgic_inject_irq (kvm,0 , irq_num, level);
arch/arm64/include/uapi/asm/kvm.h +7 -1
@@ -188,8 +188,14 @@ struct kvm_arch_memory_slot {#define KVM_ARM_IRQ_CPU_IRQ 0#define KVM_ARM_IRQ_CPU_FIQ 1 -/* Highest supported SPI, from VGIC_NR_IRQS */ +/* +* This used to hold the highest supported SPI, but it is now obsolete +* and only here to provide source code level compatibility with older +* userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS. +*/ +#ifndef __KERNEL__#define KVM_ARM_IRQ_GIC_MAX 127 +#endif /* PSCI interface */ #define KVM_PSCI_FN_BASE 0x95c1ba5e
virt/kvm/arm/vgic.c +3 -0
@@ -1371,6 +1371,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm, goto out; } +if (irq_num >= kvm->arch.vgic.nr_irqs) +return -EINVAL ; + vcpu_id =vgic_update_irq_pending (kvm, cpuid, irq_num, level);if (vcpu_id >=0 ) {/* kick the specified vcpu */
Patches currently in stable-queue which might be from [email protected] are
queue-4.0/kvm-arm-arm64-check-irq-number-on-userland-injection.patch