[PATCH] KVM: arm64: Fix buffer overflow in kvm_arm_set_fw_reg()

Steven Price steven.price at arm.com
Wed Apr 19 01:48:41 PDT 2023


On 19/04/2023 09:06, Dan Carpenter wrote:
> The KVM_REG_SIZE() comes from the ioctl and it can be a power of two
> between 0-32768 but if it is more than sizeof(long) this will corrupt
> memory.
> 
> Fixes: 99adb567632b ("KVM: arm/arm64: Add save/restore support for firmware workaround state")
> Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>

Reviewed-by: Steven Price <steven.price at arm.com>

Although there might be something to be said for rejecting anything
where KVM_REG_SIZE(reg->id) != sizeof(u64), as for smaller sizes the top
bits of val would be undefined which would require the code to mask the
top bits out to be safe. Given that all registers are currently u64 (and
I don't expect that to change), perhaps the below would be clearer?

	if (KVM_REG_SIZE(reg->id) != sizeof(val))
		return -EINVAL;
	if (copy_from_user(&val, uaddr, sizeof(val)))
		return -EFAULT;

Steve

> ---
>  arch/arm64/kvm/hypercalls.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
> index 2e16fc7b31bf..4f5767fcaca5 100644
> --- a/arch/arm64/kvm/hypercalls.c
> +++ b/arch/arm64/kvm/hypercalls.c
> @@ -544,6 +544,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
>  	u64 val;
>  	int wa_level;
>  
> +	if (KVM_REG_SIZE(reg->id) > sizeof(val))
> +		return -EINVAL;
>  	if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
>  		return -EFAULT;
>  




More information about the linux-arm-kernel mailing list