Skip to content

Commit cc8d5b2

Browse files
bibo-maochenhuacai
authored andcommitted
LoongArch: KVM: Check validity of "num_cpu" from user space
The maximum supported cpu number is EIOINTC_ROUTE_MAX_VCPUS about irqchip EIOINTC, here add validation about cpu number to avoid array pointer overflow. Cc: [email protected] Fixes: 1ad7efa ("LoongArch: KVM: Add EIOINTC user mode read and write functions") Signed-off-by: Bibo Mao <[email protected]> Signed-off-by: Huacai Chen <[email protected]>
1 parent 45515c6 commit cc8d5b2

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

arch/loongarch/kvm/intc/eiointc.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -805,16 +805,22 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
805805
int ret = 0;
806806
unsigned long flags;
807807
unsigned long type = (unsigned long)attr->attr;
808-
u32 i, start_irq;
808+
u32 i, start_irq, val;
809809
void __user *data;
810810
struct loongarch_eiointc *s = dev->kvm->arch.eiointc;
811811

812812
data = (void __user *)attr->addr;
813813
spin_lock_irqsave(&s->lock, flags);
814814
switch (type) {
815815
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU:
816-
if (copy_from_user(&s->num_cpu, data, 4))
816+
if (copy_from_user(&val, data, 4))
817817
ret = -EFAULT;
818+
else {
819+
if (val >= EIOINTC_ROUTE_MAX_VCPUS)
820+
ret = -EINVAL;
821+
else
822+
s->num_cpu = val;
823+
}
818824
break;
819825
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE:
820826
if (copy_from_user(&s->features, data, 4))
@@ -842,15 +848,15 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
842848
struct kvm_device_attr *attr,
843849
bool is_write)
844850
{
845-
int addr, cpuid, offset, ret = 0;
851+
int addr, cpu, offset, ret = 0;
846852
unsigned long flags;
847853
void *p = NULL;
848854
void __user *data;
849855
struct loongarch_eiointc *s;
850856

851857
s = dev->kvm->arch.eiointc;
852858
addr = attr->attr;
853-
cpuid = addr >> 16;
859+
cpu = addr >> 16;
854860
addr &= 0xffff;
855861
data = (void __user *)attr->addr;
856862
switch (addr) {
@@ -875,8 +881,11 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
875881
p = &s->isr.reg_u32[offset];
876882
break;
877883
case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
884+
if (cpu >= s->num_cpu)
885+
return -EINVAL;
886+
878887
offset = (addr - EIOINTC_COREISR_START) / 4;
879-
p = &s->coreisr.reg_u32[cpuid][offset];
888+
p = &s->coreisr.reg_u32[cpu][offset];
880889
break;
881890
case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
882891
offset = (addr - EIOINTC_COREMAP_START) / 4;

0 commit comments

Comments
 (0)