CVE-2021-36148 (published 2021-07-02T22:15Z)

An issue was discovered in ACRN before 2.5. dmar_free_irte in hypervisor/arch/x86/vtd.c allows an irte_alloc_bitmap buffer overflow.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 7.8, HIGH (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-120
cwe_name: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')
description: The product copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.
extended_description: A buffer overflow condition exists when a product attempts to put more data in a buffer than it can hold, or when it attempts to put data in a memory area outside of the boundaries of a buffer. The simplest type of error, and the most common cause of buffer overflows, is the "classic" case in which the product copies the buffer without restricting how much is copied. Other variants exist, but the existence of a classic overflow strongly suggests that the programmer is not considering even the most basic of security protections.
         

Fix information:
repo_url: https://github.com/projectacrn/acrn-hypervisor
commit_details: repo_url: https://github.com/projectacrn/acrn-hypervisor
author: Yonghua Huang
author_date: 2021-06-02 15:19:15+08:00
msg: hv: validate input for dmar_free_irte function

 Malicious input 'index' may trigger buffer
 overflow on array 'irte_alloc_bitmap[]'.

 This patch validate that 'index' shall be
 less than 'CONFIG_MAX_IR_ENTRIES' and also
 remove unnecessary check on 'index' in
 'ptirq_free_irte()' function with this fix.

Tracked-On: #6132
Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
repository: repo_url: https://github.com/projectacrn/acrn-hypervisor
repo_name: projectacrn/acrn-hypervisor
description: Project ACRN hypervisor 
repo_language: C
owner: projectacrn
file_changes: filename: assign.c
change_type: ModificationType.MODIFY
diff: @@ -72,16 +72,14 @@ static void ptirq_free_irte(const struct ptirq_remapping_info *entry)
 {
 	struct intr_source intr_src;
 
-	if (entry->irte_idx < CONFIG_MAX_IR_ENTRIES) {
-		if (entry->intr_type == PTDEV_INTR_MSI) {
-			intr_src.is_msi = true;
-			intr_src.src.msi.value = entry->phys_sid.msi_id.bdf;
-		} else {
-			intr_src.is_msi = false;
-			intr_src.src.ioapic_id = ioapic_irq_to_ioapic_id(entry->allocated_pirq);
-		}
-		dmar_free_irte(&intr_src, entry->irte_idx);
+	if (entry->intr_type == PTDEV_INTR_MSI) {
+		intr_src.is_msi = true;
+		intr_src.src.msi.value = entry->phys_sid.msi_id.bdf;
+	} else {
+		intr_src.is_msi = false;
+		intr_src.src.ioapic_id = ioapic_irq_to_ioapic_id(entry->allocated_pirq);
 	}
+	dmar_free_irte(&intr_src, entry->irte_idx);
 }
 
 /*

programming_language: C
filename: vtd.c
change_type: ModificationType.MODIFY
diff: @@ -1398,7 +1398,7 @@ void dmar_free_irte(const struct intr_source *intr_src, uint16_t index)
 		dmar_unit = ioapic_to_dmaru(intr_src->src.ioapic_id, &sid);
 	}
 
-	if (is_dmar_unit_valid(dmar_unit, sid)) {
+	if (is_dmar_unit_valid(dmar_unit, sid) && (index < CONFIG_MAX_IR_ENTRIES)) {
 		ir_table = (union dmar_ir_entry *)hpa2hva(dmar_unit->ir_table_addr);
 		ir_entry = ir_table + index;
 		ir_entry->bits.remap.present = 0x0UL;

programming_language: C