From 2e9028128f4f00e2a644523ed2a44d45fe63e149 Mon Sep 17 00:00:00 2001 From: Yonghua Huang Date: Mon, 20 Apr 2020 09:42:57 +0800 Subject: [PATCH] hv:bugfix in write protect page hypercall This patch fixes potential hypervisor crash when calling hc_hcall_write_protect_page()with a crafted GPA in 'struct wp_data' instance, e.g. an invalid GPA that is out of the scope of target VM's EPT address space. Tracked-On: #4669 Signed-off-by: Yonghua Huang --- hypervisor/arch/x86/ept.c | 13 +++++++++++++ hypervisor/common/hypercall.c | 7 +++++++ hypervisor/include/arch/x86/mmu.h | 13 +++++++++++++ 3 files changed, 33 insertions(+) diff --git a/hypervisor/arch/x86/ept.c b/hypervisor/arch/x86/ept.c index a3b7ce0a9..fa199c0a5 100644 --- a/hypervisor/arch/x86/ept.c +++ b/hypervisor/arch/x86/ept.c @@ -10,6 +10,19 @@ #define ACRN_DBG_EPT 6U +bool ept_is_mr_valid(const struct acrn_vm *vm, uint64_t base, uint64_t size) +{ + bool valid = true; + uint64_t end = base + size; + uint64_t top_address_space = vm->arch_vm.ept_mem_ops.info->ept.top_address_space; + + if ((end <= base) || (end > top_address_space)) { + valid = false; + } + + return valid; +} + void destroy_ept(struct acrn_vm *vm) { /* Destroy secure world */ diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 6adb32eb0..c32e31f0a 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -635,6 +635,13 @@ static int32_t write_protect_page(struct acrn_vm *vm,const struct wp_data *wp) uint64_t prot_set; uint64_t prot_clr; + if ((!mem_aligned_check(wp->gpa, PAGE_SIZE)) || + (!ept_is_mr_valid(vm, wp->gpa, PAGE_SIZE))) { + pr_err("%s,vm[%hu] gpa 0x%lx,GPA is invalid or not page size aligned.", + __func__, vm->vm_id, wp->gpa); + return -EINVAL; + } + hpa = gpa2hpa(vm, wp->gpa); if (hpa == INVALID_HPA) { pr_err("%s,vm[%hu] gpa 0x%llx,GPA is unmapping.", diff --git a/hypervisor/include/arch/x86/mmu.h b/hypervisor/include/arch/x86/mmu.h index 1f7dae576..1a8e6c9bd 100644 --- a/hypervisor/include/arch/x86/mmu.h +++ b/hypervisor/include/arch/x86/mmu.h @@ -219,6 +219,19 @@ static inline void clflush(volatile void *p) #define INVALID_HPA (0x1UL << 52U) #define INVALID_GPA (0x1UL << 52U) /* External Interfaces */ + +/** + * @brief Check guest-physical memory region mapping valid + * + * @param[in] vm the pointer that points to VM data structure + * @param[in] base The specified start guest physical address of guest + * physical memory region + * @param[in] size The size of guest physical memory region + * + * @retval true if the guest-physical memory region mapping valid, false otherwise. + */ +bool ept_is_mr_valid(const struct acrn_vm *vm, uint64_t base, uint64_t size); + /** * @brief EPT page tables destroy *