From 868778a68b5ef6eee571cc2b17f5bb4ef3d0773b Mon Sep 17 00:00:00 2001 From: Yonghua Huang Date: Tue, 26 Mar 2019 01:37:46 +0800 Subject: [PATCH] hv: fix vulnerability when VM is destroyed In hypervisor fuzzing test, hypervisor will hang if issuing HV_VM_SET_MEMORY_REGIONS hypercall after target VM is destroyed. this patch is to fix above vulnerability. Tracked-On: #2849 Signed-off-by: Yonghua Huang Acked-by: Anthony Xu --- hypervisor/arch/x86/guest/vm.c | 2 ++ hypervisor/common/hypercall.c | 13 ++++++------- hypervisor/include/arch/x86/guest/vm.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 981a0b9de..498143653 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -448,6 +448,8 @@ int32_t shutdown_vm(struct acrn_vm *vm) /* Only allow shutdown paused vm */ if (vm->state == VM_PAUSED) { + vm->state = VM_STATE_INVALID; + foreach_vcpu(i, vm, vcpu) { reset_vcpu(vcpu); offline_vcpu(vcpu); diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 1c9acdbe4..ee0c50be8 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -665,20 +665,19 @@ int32_t hcall_set_vm_memory_regions(struct acrn_vm *vm, uint64_t param) struct set_regions regions; struct vm_memory_region mr; struct acrn_vm *target_vm; + uint16_t target_vm_id; uint32_t idx; - int32_t ret = 0; + int32_t ret = -EFAULT; (void)memset((void *)®ions, 0U, sizeof(regions)); - if (copy_from_gpa(vm, ®ions, param, sizeof(regions)) != 0) { - pr_err("%s: Unable copy param from vm\n", __func__); - ret = -EFAULT; - } else { + if (copy_from_gpa(vm, ®ions, param, sizeof(regions)) == 0) { target_vm = get_vm_from_vmid(regions.vmid); - if ((target_vm == NULL) || is_sos_vm(target_vm)) { + target_vm_id = target_vm->vm_id; + if ((target_vm_id >= CONFIG_MAX_VM_NUM) || (get_vm_config(target_vm_id)->type != NORMAL_VM) + || (target_vm->state == VM_STATE_INVALID)) { pr_err("%p %s:target_vm is invalid or Targeting to service vm", target_vm, __func__); - ret = -EFAULT; } else { idx = 0U; while (idx < regions.mr_num) { diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index bd83961ee..f74b6272b 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -85,7 +85,7 @@ struct vm_pm_info { #define VM_MONO_GUEST 0x01 /* Enumerated type for VM states */ enum vm_state { - VM_STATE_UNKNOWN = 0, + VM_STATE_INVALID = 0, VM_CREATED, /* VM created / awaiting start (boot) */ VM_STARTED, /* VM started (booted) */ VM_PAUSED, /* VM paused */