hv: add sanity check for vuart configuration

- target vm_id of vuart can't be un-defined VM, nor the VM itself.
- fix potential NULL pointer dereference in find_active_target_vuart()

Tracked-On: #3854
Signed-off-by: Zide Chen <zide.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Zide Chen 2019-12-24 10:49:13 -08:00 committed by wenlingz
parent c6f7803f06
commit 742abaf2e6
2 changed files with 22 additions and 8 deletions

View File

@ -9,6 +9,7 @@
#include <logmsg.h>
#include <cat.h>
#include <pgtable.h>
#include <vuart.h>
static uint8_t rtvm_uuid1[16] = RTVM_UUID1;
static uint8_t safety_vm_uuid1[16] = SAFETY_VM_UUID1;
@ -93,7 +94,7 @@ static bool check_vm_uuid_collision(uint16_t vm_id)
bool sanitize_vm_config(void)
{
bool ret = true;
uint16_t vm_id, vcpu_id, nr;
uint16_t vm_id, vcpu_id, vuart_idx, nr;
uint64_t sos_pcpu_bitmap, pre_launch_pcpu_bitmap = 0U, vm_pcpu_bitmap;
struct acrn_vm_config *vm_config;
@ -200,6 +201,20 @@ bool sanitize_vm_config(void)
/* make sure no identical UUID in following VM configurations */
ret = check_vm_uuid_collision(vm_id);
}
/* vuart[1+] are used for VM communications */
for (vuart_idx = 1U; vuart_idx < MAX_VUART_NUM_PER_VM; vuart_idx++) {
const struct vuart_config *vu_config = &vm_config->vuart[vuart_idx];
if (!(vu_config->type == VUART_LEGACY_PIO) && (vu_config->addr.port_base == INVALID_COM_BASE)) {
if ((vu_config->t_vuart.vm_id >= CONFIG_MAX_VM_NUM) ||
(vu_config->t_vuart.vm_id == vm_id)) {
pr_err("%s invalid vuart configuration for VM %d\n", __func__, vm_id);
ret = false;
}
}
}
if (!ret) {
break;
}

View File

@ -580,17 +580,16 @@ static struct acrn_vuart *find_active_target_vuart(const struct vuart_config *vu
target_vmid = vu_config->t_vuart.vm_id;
target_vuid = vu_config->t_vuart.vuart_id;
if (target_vmid < CONFIG_MAX_VM_NUM) {
if ((target_vmid < CONFIG_MAX_VM_NUM) && (target_vuid < MAX_VUART_NUM_PER_VM)) {
target_vm = get_vm_from_vmid(target_vmid);
}
if (target_vuid < MAX_VUART_NUM_PER_VM) {
target_vu = &target_vm->vuart[target_vuid];
if ((target_vu != NULL) && (target_vu->active)) {
ret_vu = target_vu;
}
}
if ((target_vu != NULL) && (target_vu->active)) {
ret_vu = target_vu;
}
return ret_vu;
}