Skip to content

Commit 1d487e9

Browse files
committed
KVM: fix spectrev1 gadgets
These were found with smatch, and then generalized when applicable. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent be43c44 commit 1d487e9

File tree

4 files changed

+16
-9
lines changed

4 files changed

+16
-9
lines changed

arch/x86/kvm/lapic.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map,
138138
if (offset <= max_apic_id) {
139139
u8 cluster_size = min(max_apic_id - offset + 1, 16U);
140140

141+
offset = array_index_nospec(offset, map->max_apic_id + 1);
141142
*cluster = &map->phys_map[offset];
142143
*mask = dest_id & (0xffff >> (16 - cluster_size));
143144
} else {
@@ -901,7 +902,8 @@ static inline bool kvm_apic_map_get_dest_lapic(struct kvm *kvm,
901902
if (irq->dest_id > map->max_apic_id) {
902903
*bitmap = 0;
903904
} else {
904-
*dst = &map->phys_map[irq->dest_id];
905+
u32 dest_id = array_index_nospec(irq->dest_id, map->max_apic_id + 1);
906+
*dst = &map->phys_map[dest_id];
905907
*bitmap = 1;
906908
}
907909
return true;

include/linux/kvm_host.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <linux/irqbypass.h>
2929
#include <linux/swait.h>
3030
#include <linux/refcount.h>
31+
#include <linux/nospec.h>
3132
#include <asm/signal.h>
3233

3334
#include <linux/kvm.h>
@@ -513,10 +514,10 @@ static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx)
513514

514515
static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
515516
{
516-
/* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu, in case
517-
* the caller has read kvm->online_vcpus before (as is the case
518-
* for kvm_for_each_vcpu, for example).
519-
*/
517+
int num_vcpus = atomic_read(&kvm->online_vcpus);
518+
i = array_index_nospec(i, num_vcpus);
519+
520+
/* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */
520521
smp_rmb();
521522
return kvm->vcpus[i];
522523
}
@@ -600,6 +601,7 @@ void kvm_put_kvm(struct kvm *kvm);
600601

601602
static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)
602603
{
604+
as_id = array_index_nospec(as_id, KVM_ADDRESS_SPACE_NUM);
603605
return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu,
604606
lockdep_is_held(&kvm->slots_lock) ||
605607
!refcount_read(&kvm->users_count));

virt/kvm/irqchip.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,19 @@ static int setup_routing_entry(struct kvm *kvm,
144144
{
145145
struct kvm_kernel_irq_routing_entry *ei;
146146
int r;
147+
u32 gsi = array_index_nospec(ue->gsi, KVM_MAX_IRQ_ROUTES);
147148

148149
/*
149150
* Do not allow GSI to be mapped to the same irqchip more than once.
150151
* Allow only one to one mapping between GSI and non-irqchip routing.
151152
*/
152-
hlist_for_each_entry(ei, &rt->map[ue->gsi], link)
153+
hlist_for_each_entry(ei, &rt->map[gsi], link)
153154
if (ei->type != KVM_IRQ_ROUTING_IRQCHIP ||
154155
ue->type != KVM_IRQ_ROUTING_IRQCHIP ||
155156
ue->u.irqchip.irqchip == ei->irqchip.irqchip)
156157
return -EINVAL;
157158

158-
e->gsi = ue->gsi;
159+
e->gsi = gsi;
159160
e->type = ue->type;
160161
r = kvm_set_routing_entry(kvm, e, ue);
161162
if (r)

virt/kvm/kvm_main.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2977,12 +2977,14 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
29772977
struct kvm_device_ops *ops = NULL;
29782978
struct kvm_device *dev;
29792979
bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
2980+
int type;
29802981
int ret;
29812982

29822983
if (cd->type >= ARRAY_SIZE(kvm_device_ops_table))
29832984
return -ENODEV;
29842985

2985-
ops = kvm_device_ops_table[cd->type];
2986+
type = array_index_nospec(cd->type, ARRAY_SIZE(kvm_device_ops_table));
2987+
ops = kvm_device_ops_table[type];
29862988
if (ops == NULL)
29872989
return -ENODEV;
29882990

@@ -2997,7 +2999,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
29972999
dev->kvm = kvm;
29983000

29993001
mutex_lock(&kvm->lock);
3000-
ret = ops->create(dev, cd->type);
3002+
ret = ops->create(dev, type);
30013003
if (ret < 0) {
30023004
mutex_unlock(&kvm->lock);
30033005
kfree(dev);

0 commit comments

Comments
 (0)