⬢ DragonFlyBSD Kernel Audit
DF-5579 / fix.diff
← back to finding ↓ download raw
diff --git a/a/sys/platform/vkernel64/x86_64/vm_machdep.c b/b/sys/platform/vkernel64/x86_64/vm_machdep.c
index 818623b..df912a5 100644
--- a/a/sys/platform/vkernel64/x86_64/vm_machdep.c
+++ b/b/sys/platform/vkernel64/x86_64/vm_machdep.c
@@ -319,6 +319,17 @@ kvm_access_check(vm_offset_t saddr, vm_offset_t eaddr, int prot)
 		return EFAULT;
 	if (eaddr >= KvaEnd)
 		return EFAULT;
+
+	/*
+	 * Only the grown portion of the kernel page tables can be walked
+	 * safely.  pmap_kextract() dereferences vtopde(), which asserts
+	 * (and thus SIGABRTs the whole vkernel) when the 1GB PDPT entry
+	 * covering the address was never grown by pmap_growkernel().
+	 * kernel_vm_end is the grown frontier (absolute VA, pmap.c).
+	 */
+	if (eaddr > kernel_vm_end)
+		return EFAULT;
+
 	for (addr = saddr; addr < eaddr; addr += PAGE_SIZE)  {
 		if (pmap_kextract(addr) == 0)
 			return EFAULT;