⬢ DragonFlyBSD Kernel Audit
DF-5588 / fix.diff
← back to finding ↓ download raw
--- sys/platform/pc64/acpica/acpi_sdt.c
+++ sys/platform/pc64/acpica/acpi_sdt.c
@@ -68,12 +68,30 @@
 	uint8_t *ptr;
 	u_long rsdp_paddr;
 
-	if (kgetenv_ulong("hint.acpi.0.rsdp", &rsdp_paddr) == 1) {
-		SDT_VPRINTF("RSDP in kenv hint\n");
+	/*
+	 * The hinted RSDP address must refer to physical memory
+	 * (mapping an address with reserved PTE bits faults the
+	 * moment the mapping is read), and the bytes it points at
+	 * must actually look like an RSDP with a revision we
+	 * understand before it is installed as the ACPI table root.
+	 * Otherwise fall back to the firmware scan below.
+	 */
+	if (kgetenv_ulong("hint.acpi.0.rsdp", &rsdp_paddr) == 1 &&
+	    rsdp_paddr < ptoa(Maxmem)) {
 		mapsz = PAGE_SIZE;
 		ptr = pmap_mapdev(rsdp_paddr, mapsz);
 		rsdp = (const ACPI_TABLE_RSDP *)ptr;
-		goto found_rsdp;
+		if (memcmp(rsdp->Signature, ACPI_SIG_RSDP,
+			   sizeof(rsdp->Signature)) == 0 &&
+		    rsdp->Revision <= 2) {
+			SDT_VPRINTF("RSDP in kenv hint\n");
+			goto found_rsdp;
+		}
+		kprintf("sdt_probe: kenv RSDP failed validation, "
+			"falling back to firmware scan\n");
+		pmap_unmapdev((vm_offset_t)ptr, mapsz);
+		ptr = NULL;
+		mapsz = 0;
 	}
 
 	if (ebda_addr != 0) {