diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c index 62d2fb77bb9b..3708616e2c32 100644 --- a/arch/riscv/kvm/vcpu_vector.c +++ b/arch/riscv/kvm/vcpu_vector.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -129,11 +130,20 @@ static int kvm_riscv_vcpu_vreg_addr(struct kvm_vcpu *vcpu, return -ENOENT; } } else if (reg_num <= KVM_REG_RISCV_VECTOR_REG(31)) { + unsigned long reg_offset; + if (reg_size != vlenb) return -EINVAL; WARN_ON(!cntx->vector.datap); - *reg_addr = cntx->vector.datap + - (reg_num - KVM_REG_RISCV_VECTOR_REG(0)) * vlenb; + /* + * The reg_num is derived from the userspace-provided ONE_REG + * id. Sanitize it with array_index_nospec() to prevent + * speculative out-of-bounds access to the vector register + * buffer (32 vector registers: v0..v31). + */ + reg_offset = array_index_nospec( + reg_num - KVM_REG_RISCV_VECTOR_REG(0), 32); + *reg_addr = cntx->vector.datap + reg_offset * vlenb; } else { return -ENOENT; }