From 8dd471b37de7088f91a30a5af8440ccae361f72e Mon Sep 17 00:00:00 2001 From: Tianhua Sun Date: Wed, 29 May 2019 16:45:01 +0800 Subject: [PATCH] hv: fix possible null pointer dereference This patch fix potential null pointer dereference 1, will access null pointer if 'context' is null. 2, if entry already been added to the VM when add intx entry for this vm, but parameter virt_pin is not equal to entry->virt_sid.intx_id.pin. So will saves this entry address to vpin_to_pt_entry[entry->virt_sid.intx_id.pin] and vpin_to_pt_entry[virt_pin]. In this case, this entry will be freed twice. Tracked-On: #3217 Signed-off-by: Tianhua Sun Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/assign.c | 4 +++- hypervisor/arch/x86/vtd.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hypervisor/arch/x86/guest/assign.c b/hypervisor/arch/x86/guest/assign.c index a21425eb23..8a9f5c6021 100644 --- a/hypervisor/arch/x86/guest/assign.c +++ b/hypervisor/arch/x86/guest/assign.c @@ -358,6 +358,7 @@ static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint3 uint32_t phys_pin, bool pic_pin) { struct ptirq_remapping_info *entry = NULL; + bool entry_is_updated = true; uint32_t vpin_src = pic_pin ? PTDEV_VPIN_PIC : PTDEV_VPIN_IOAPIC; DEFINE_IOAPIC_SID(phys_sid, phys_pin, 0U); DEFINE_IOAPIC_SID(virt_sid, virt_pin, vpin_src); @@ -398,9 +399,10 @@ static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint3 } else { /* The mapping has already been added to the VM. No action * required. */ + entry_is_updated = false; } - if (entry != NULL) { + if (entry != NULL && entry_is_updated) { if (pic_pin) { vm->arch_vm.vpic.vpin_to_pt_entry[virt_pin] = entry; } else { diff --git a/hypervisor/arch/x86/vtd.c b/hypervisor/arch/x86/vtd.c index 9b2d1e2e4e..1a1a0aea21 100644 --- a/hypervisor/arch/x86/vtd.c +++ b/hypervisor/arch/x86/vtd.c @@ -1182,7 +1182,7 @@ static int32_t remove_iommu_device(const struct iommu_domain *domain, uint16_t s context_entry = context + devfun; - if (context_entry == NULL) { + if (context == NULL || context_entry == NULL) { pr_err("dmar context entry is invalid"); ret = -EINVAL; } else if ((uint16_t)dmar_get_bitslice(context_entry->hi_64, CTX_ENTRY_UPPER_DID_MASK, CTX_ENTRY_UPPER_DID_POS) != vmid_to_domainid(domain->vm_id)) {