mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 20:22:46 +00:00
HV:refine 'create_vm()' to avoid potential crash and memory leak
hypervisor will crash if user try to call hypercall HC_CREATE_VM in infinite style. actually, the number of VMs hypervisor can support depends on the bit width of 'vmid_bitmap'.should return error in case of overflow. other cleanup for this function to avoid memory leak in case of failure. Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
53a5941b99
commit
45d6f72b51
@ -99,14 +99,21 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
||||
if (vm->hw.vcpu_array == NULL) {
|
||||
pr_err("%s, vcpu_array allocation failed\n", __func__);
|
||||
status = -ENOMEM;
|
||||
goto err1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (id = 0U; id < (size_t)(sizeof(long) * 8U); id++) {
|
||||
for (id = 0U; id < (size_t)(sizeof(vmid_bitmap) * 8U); id++) {
|
||||
if (!bitmap_test_and_set(id, &vmid_bitmap)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id >= (size_t)(sizeof(vmid_bitmap) * 8U)) {
|
||||
pr_err("%s, no more VMs can be supported\n", __func__);
|
||||
status = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
vm->attr.id = id;
|
||||
vm->attr.boot_idx = id;
|
||||
|
||||
@ -120,7 +127,8 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
||||
if ((vm->arch_vm.nworld_eptp == NULL) ||
|
||||
(vm->arch_vm.m2p == NULL)) {
|
||||
pr_fatal("%s, alloc memory for EPTP failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
status = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Only for SOS: Configure VM software information */
|
||||
@ -128,12 +136,12 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
||||
if (is_vm0(vm)) {
|
||||
status = prepare_vm0_memmap_and_e820(vm);
|
||||
if (status != 0) {
|
||||
goto err2;
|
||||
goto err;
|
||||
}
|
||||
#ifndef CONFIG_EFI_STUB
|
||||
status = init_vm0_boot_info(vm);
|
||||
if (status != 0) {
|
||||
goto err2;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
@ -175,7 +183,7 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
||||
vm->arch_vm.virt_ioapic = vioapic_init(vm);
|
||||
if (vm->arch_vm.virt_ioapic == NULL) {
|
||||
status = -ENODEV;
|
||||
goto err3;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Populate return VM handle */
|
||||
@ -184,20 +192,34 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
||||
|
||||
status = set_vcpuid_entries(vm);
|
||||
if (status != 0) {
|
||||
goto err4;
|
||||
goto err;
|
||||
}
|
||||
|
||||
vm->state = VM_CREATED;
|
||||
|
||||
return 0;
|
||||
|
||||
err4:
|
||||
vioapic_cleanup(vm->arch_vm.virt_ioapic);
|
||||
err3:
|
||||
vpic_cleanup(vm);
|
||||
err2:
|
||||
free(vm->hw.vcpu_array);
|
||||
err1:
|
||||
err:
|
||||
if (vm->arch_vm.virt_ioapic != NULL) {
|
||||
vioapic_cleanup(vm->arch_vm.virt_ioapic);
|
||||
}
|
||||
|
||||
if (vm->vpic != NULL) {
|
||||
vpic_cleanup(vm);
|
||||
}
|
||||
|
||||
if (vm->arch_vm.m2p != NULL) {
|
||||
free(vm->arch_vm.m2p);
|
||||
}
|
||||
|
||||
if (vm->arch_vm.nworld_eptp != NULL) {
|
||||
free(vm->arch_vm.nworld_eptp);
|
||||
}
|
||||
|
||||
if (vm->hw.vcpu_array != NULL) {
|
||||
free(vm->hw.vcpu_array);
|
||||
}
|
||||
|
||||
free(vm);
|
||||
return status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user