Skip to content

Commit 45d6f72

Browse files
yonghuahlijinxia
authored andcommitted
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>
1 parent 53a5941 commit 45d6f72

File tree

1 file changed

+36
-14
lines changed
  • hypervisor/arch/x86/guest

1 file changed

+36
-14
lines changed

hypervisor/arch/x86/guest/vm.c

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,21 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
9999
if (vm->hw.vcpu_array == NULL) {
100100
pr_err("%s, vcpu_array allocation failed\n", __func__);
101101
status = -ENOMEM;
102-
goto err1;
102+
goto err;
103103
}
104104

105-
for (id = 0U; id < (size_t)(sizeof(long) * 8U); id++) {
105+
for (id = 0U; id < (size_t)(sizeof(vmid_bitmap) * 8U); id++) {
106106
if (!bitmap_test_and_set(id, &vmid_bitmap)) {
107107
break;
108108
}
109109
}
110+
111+
if (id >= (size_t)(sizeof(vmid_bitmap) * 8U)) {
112+
pr_err("%s, no more VMs can be supported\n", __func__);
113+
status = -EINVAL;
114+
goto err;
115+
}
116+
110117
vm->attr.id = id;
111118
vm->attr.boot_idx = id;
112119

@@ -120,20 +127,21 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
120127
if ((vm->arch_vm.nworld_eptp == NULL) ||
121128
(vm->arch_vm.m2p == NULL)) {
122129
pr_fatal("%s, alloc memory for EPTP failed\n", __func__);
123-
return -ENOMEM;
130+
status = -ENOMEM;
131+
goto err;
124132
}
125133

126134
/* Only for SOS: Configure VM software information */
127135
/* For UOS: This VM software information is configure in DM */
128136
if (is_vm0(vm)) {
129137
status = prepare_vm0_memmap_and_e820(vm);
130138
if (status != 0) {
131-
goto err2;
139+
goto err;
132140
}
133141
#ifndef CONFIG_EFI_STUB
134142
status = init_vm0_boot_info(vm);
135143
if (status != 0) {
136-
goto err2;
144+
goto err;
137145
}
138146
#endif
139147
} else {
@@ -175,7 +183,7 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
175183
vm->arch_vm.virt_ioapic = vioapic_init(vm);
176184
if (vm->arch_vm.virt_ioapic == NULL) {
177185
status = -ENODEV;
178-
goto err3;
186+
goto err;
179187
}
180188

181189
/* Populate return VM handle */
@@ -184,20 +192,34 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
184192

185193
status = set_vcpuid_entries(vm);
186194
if (status != 0) {
187-
goto err4;
195+
goto err;
188196
}
189197

190198
vm->state = VM_CREATED;
191199

192200
return 0;
193201

194-
err4:
195-
vioapic_cleanup(vm->arch_vm.virt_ioapic);
196-
err3:
197-
vpic_cleanup(vm);
198-
err2:
199-
free(vm->hw.vcpu_array);
200-
err1:
202+
err:
203+
if (vm->arch_vm.virt_ioapic != NULL) {
204+
vioapic_cleanup(vm->arch_vm.virt_ioapic);
205+
}
206+
207+
if (vm->vpic != NULL) {
208+
vpic_cleanup(vm);
209+
}
210+
211+
if (vm->arch_vm.m2p != NULL) {
212+
free(vm->arch_vm.m2p);
213+
}
214+
215+
if (vm->arch_vm.nworld_eptp != NULL) {
216+
free(vm->arch_vm.nworld_eptp);
217+
}
218+
219+
if (vm->hw.vcpu_array != NULL) {
220+
free(vm->hw.vcpu_array);
221+
}
222+
201223
free(vm);
202224
return status;
203225
}

0 commit comments

Comments
 (0)