mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-25 23:13:26 +00:00
add IO requrest 'req_buf' check before reference
This address maybe invalid if a hostile address was set in hypercall 'HC_SET_IOREQ_BUFFER'.it should be validated before using. Update: -- save HVA to guest OS's request buffer in hyperviosr -- change type of 'req_buf' from 'uint64_t' to 'void *' -- remove HPA to HVA translation code when using this addr. -- use error number instead of -1 when return error cases. Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
This commit is contained in:
parent
3a3aeac09f
commit
9b37e1464c
@ -344,8 +344,9 @@ int dm_emulate_mmio_post(struct vcpu *vcpu)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int cur = vcpu->vcpu_id;
|
int cur = vcpu->vcpu_id;
|
||||||
struct vhm_request_buffer *req_buf =
|
struct vhm_request_buffer *req_buf;
|
||||||
(void *)HPA2HVA(vcpu->vm->sw.req_buf);
|
|
||||||
|
req_buf = (struct vhm_request_buffer *)(vcpu->vm->sw.req_buf);
|
||||||
|
|
||||||
vcpu->req.reqs.mmio_request.value =
|
vcpu->req.reqs.mmio_request.value =
|
||||||
req_buf->req_queue[cur].reqs.mmio_request.value;
|
req_buf->req_queue[cur].reqs.mmio_request.value;
|
||||||
|
@ -170,7 +170,7 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
|
|||||||
|
|
||||||
/* Populate return VM handle */
|
/* Populate return VM handle */
|
||||||
*rtn_vm = vm;
|
*rtn_vm = vm;
|
||||||
vm->sw.req_buf = 0;
|
vm->sw.req_buf = NULL;
|
||||||
|
|
||||||
status = set_vcpuid_entries(vm);
|
status = set_vcpuid_entries(vm);
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -39,12 +39,13 @@ int dm_emulate_pio_post(struct vcpu *vcpu)
|
|||||||
{
|
{
|
||||||
int cur = vcpu->vcpu_id;
|
int cur = vcpu->vcpu_id;
|
||||||
int cur_context = vcpu->arch_vcpu.cur_context;
|
int cur_context = vcpu->arch_vcpu.cur_context;
|
||||||
struct vhm_request_buffer *req_buf =
|
struct vhm_request_buffer *req_buf = NULL;
|
||||||
(void *)HPA2HVA(vcpu->vm->sw.req_buf);
|
|
||||||
uint32_t mask =
|
uint32_t mask =
|
||||||
0xFFFFFFFFul >> (32 - 8 * vcpu->req.reqs.pio_request.size);
|
0xFFFFFFFFul >> (32 - 8 * vcpu->req.reqs.pio_request.size);
|
||||||
uint64_t *rax;
|
uint64_t *rax;
|
||||||
|
|
||||||
|
req_buf = (struct vhm_request_buffer *)(vcpu->vm->sw.req_buf);
|
||||||
|
|
||||||
rax = &vcpu->arch_vcpu.contexts[cur_context].guest_cpu_regs.regs.rax;
|
rax = &vcpu->arch_vcpu.contexts[cur_context].guest_cpu_regs.regs.rax;
|
||||||
vcpu->req.reqs.pio_request.value =
|
vcpu->req.reqs.pio_request.value =
|
||||||
req_buf->req_queue[cur].reqs.pio_request.value;
|
req_buf->req_queue[cur].reqs.pio_request.value;
|
||||||
|
@ -213,7 +213,7 @@ int64_t hcall_resume_vm(uint64_t vmid)
|
|||||||
|
|
||||||
if (target_vm == NULL)
|
if (target_vm == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (target_vm->sw.req_buf == 0)
|
if (target_vm->sw.req_buf == NULL)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
else
|
else
|
||||||
ret = start_vm(target_vm);
|
ret = start_vm(target_vm);
|
||||||
@ -323,6 +323,7 @@ int64_t hcall_inject_msi(struct vm *vm, uint64_t vmid, uint64_t param)
|
|||||||
int64_t hcall_set_ioreq_buffer(struct vm *vm, uint64_t vmid, uint64_t param)
|
int64_t hcall_set_ioreq_buffer(struct vm *vm, uint64_t vmid, uint64_t param)
|
||||||
{
|
{
|
||||||
int64_t ret = 0;
|
int64_t ret = 0;
|
||||||
|
uint64_t hpa = 0;
|
||||||
struct acrn_set_ioreq_buffer iobuf;
|
struct acrn_set_ioreq_buffer iobuf;
|
||||||
struct vm *target_vm = get_vm_from_vmid(vmid);
|
struct vm *target_vm = get_vm_from_vmid(vmid);
|
||||||
|
|
||||||
@ -336,11 +337,17 @@ int64_t hcall_set_ioreq_buffer(struct vm *vm, uint64_t vmid, uint64_t param)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(ACRN_DBG_HYCALL, "[%d] SET BUFFER=0x%x",
|
dev_dbg(ACRN_DBG_HYCALL, "[%d] SET BUFFER=0x%p",
|
||||||
vmid, iobuf.req_buf);
|
vmid, iobuf.req_buf);
|
||||||
|
|
||||||
/* store gpa of guest request_buffer */
|
hpa = gpa2hpa(vm, iobuf.req_buf);
|
||||||
target_vm->sw.req_buf = gpa2hpa(vm, iobuf.req_buf);
|
if (hpa == 0) {
|
||||||
|
pr_err("%s: invalid GPA.\n", __func__);
|
||||||
|
target_vm->sw.req_buf = NULL;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_vm->sw.req_buf = HPA2HVA(hpa);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -386,8 +393,8 @@ int64_t hcall_notify_req_finish(uint64_t vmid, uint64_t vcpu_id)
|
|||||||
struct vm *target_vm = get_vm_from_vmid(vmid);
|
struct vm *target_vm = get_vm_from_vmid(vmid);
|
||||||
|
|
||||||
/* make sure we have set req_buf */
|
/* make sure we have set req_buf */
|
||||||
if (!target_vm || target_vm->sw.req_buf == 0)
|
if (!target_vm || target_vm->sw.req_buf == NULL)
|
||||||
return -1;
|
return -EINVAL;
|
||||||
|
|
||||||
dev_dbg(ACRN_DBG_HYCALL, "[%d] NOTIFY_FINISH for vcpu %d",
|
dev_dbg(ACRN_DBG_HYCALL, "[%d] NOTIFY_FINISH for vcpu %d",
|
||||||
vmid, vcpu_id);
|
vmid, vcpu_id);
|
||||||
@ -779,16 +786,17 @@ static void acrn_print_request(int vcpu_id, struct vhm_request *req)
|
|||||||
|
|
||||||
int acrn_insert_request_wait(struct vcpu *vcpu, struct vhm_request *req)
|
int acrn_insert_request_wait(struct vcpu *vcpu, struct vhm_request *req)
|
||||||
{
|
{
|
||||||
struct vhm_request_buffer *req_buf =
|
struct vhm_request_buffer *req_buf = NULL;
|
||||||
(void *)HPA2HVA(vcpu->vm->sw.req_buf);
|
|
||||||
long cur;
|
long cur;
|
||||||
|
|
||||||
ASSERT(sizeof(*req) == (4096/VHM_REQUEST_MAX),
|
ASSERT(sizeof(*req) == (4096/VHM_REQUEST_MAX),
|
||||||
"vhm_request page broken!");
|
"vhm_request page broken!");
|
||||||
|
|
||||||
|
|
||||||
if (!vcpu || !req || vcpu->vm->sw.req_buf == 0)
|
if (!vcpu || !req || vcpu->vm->sw.req_buf == NULL)
|
||||||
return -1;
|
return -EINVAL;
|
||||||
|
|
||||||
|
req_buf = (struct vhm_request_buffer *)(vcpu->vm->sw.req_buf);
|
||||||
|
|
||||||
/* ACRN insert request to VHM and inject upcall */
|
/* ACRN insert request to VHM and inject upcall */
|
||||||
cur = vcpu->vcpu_id;
|
cur = vcpu->vcpu_id;
|
||||||
@ -820,9 +828,9 @@ int acrn_insert_request_nowait(struct vcpu *vcpu, struct vhm_request *req)
|
|||||||
long cur;
|
long cur;
|
||||||
|
|
||||||
if (!vcpu || !req || !vcpu->vm->sw.req_buf)
|
if (!vcpu || !req || !vcpu->vm->sw.req_buf)
|
||||||
return -1;
|
return -EINVAL;
|
||||||
|
|
||||||
req_buf = (void *)gpa2hpa(vcpu->vm, vcpu->vm->sw.req_buf);
|
req_buf = (struct vhm_request_buffer *)(vcpu->vm->sw.req_buf);
|
||||||
|
|
||||||
/* ACRN insert request to VHM and inject upcall */
|
/* ACRN insert request to VHM and inject upcall */
|
||||||
cur = vcpu->vcpu_id;
|
cur = vcpu->vcpu_id;
|
||||||
|
@ -76,8 +76,8 @@ struct vm_sw_info {
|
|||||||
struct sw_kernel_info kernel_info;
|
struct sw_kernel_info kernel_info;
|
||||||
/* Additional information specific to Linux guests */
|
/* Additional information specific to Linux guests */
|
||||||
struct sw_linux linux_info;
|
struct sw_linux linux_info;
|
||||||
/* GPA Address of guest OS's request buffer */
|
/* HVA to guest OS's request buffer */
|
||||||
uint64_t req_buf;
|
void *req_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vm_pm_info {
|
struct vm_pm_info {
|
||||||
|
Loading…
Reference in New Issue
Block a user