summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2018-04-25 12:13:41 -0400
committerWill Deacon <will.deacon@arm.com>2018-04-26 12:02:37 -0400
commit41b87599c74300027f305d7b34368ec558978ff2 (patch)
tree9d2911554c552c48dc3b764708aa7d96bbe6f348 /virt
parent19791a7ca674fb3009bb068260e852a2f05b605c (diff)
KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_get_irq()
It's possible for userspace to control intid. Sanitize intid when using it as an array index. At the same time, sort the includes when adding <linux/nospec.h>. Found by smatch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Christoffer Dall <christoffer.dall@arm.com> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Cc: kvmarm@lists.cs.columbia.edu Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic/vgic.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index e74baec76361..bd125563b15b 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -14,11 +14,13 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/interrupt.h>
18#include <linux/irq.h>
17#include <linux/kvm.h> 19#include <linux/kvm.h>
18#include <linux/kvm_host.h> 20#include <linux/kvm_host.h>
19#include <linux/list_sort.h> 21#include <linux/list_sort.h>
20#include <linux/interrupt.h> 22#include <linux/nospec.h>
21#include <linux/irq.h> 23
22#include <asm/kvm_hyp.h> 24#include <asm/kvm_hyp.h>
23 25
24#include "vgic.h" 26#include "vgic.h"
@@ -101,12 +103,16 @@ struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu,
101 u32 intid) 103 u32 intid)
102{ 104{
103 /* SGIs and PPIs */ 105 /* SGIs and PPIs */
104 if (intid <= VGIC_MAX_PRIVATE) 106 if (intid <= VGIC_MAX_PRIVATE) {
107 intid = array_index_nospec(intid, VGIC_MAX_PRIVATE);
105 return &vcpu->arch.vgic_cpu.private_irqs[intid]; 108 return &vcpu->arch.vgic_cpu.private_irqs[intid];
109 }
106 110
107 /* SPIs */ 111 /* SPIs */
108 if (intid <= VGIC_MAX_SPI) 112 if (intid <= VGIC_MAX_SPI) {
113 intid = array_index_nospec(intid, VGIC_MAX_SPI);
109 return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS]; 114 return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS];
115 }
110 116
111 /* LPIs */ 117 /* LPIs */
112 if (intid >= VGIC_MIN_LPI) 118 if (intid >= VGIC_MIN_LPI)