⬢ DragonFlyBSD Kernel Audit
DF-5536 / fix.diff
← back to finding ↓ download raw
--- a/sys/platform/pc64/x86_64/minidump_machdep.c
+++ b/sys/platform/pc64/x86_64/minidump_machdep.c
@@ -235,7 +235,7 @@
 		 * contains NKPML4E PDP pages (so we can get to all kernel
 		 * PD entries from this array).
 		 */
-		i = ((va - VM_MIN_KERNEL_ADDRESS) >> PDPSHIFT) &
+		i = ((va - KPDPPHYS_KVA) >> PDPSHIFT) &
 		    (NPML4EPG * NPDPEPG - 1);
 		if (i != lpdp) {
 			lpdp = i;
@@ -249,10 +249,12 @@
 		 *
 		 * We include the PD entries in the PDP in the dump
 		 */
-		i = ((va - VM_MIN_KERNEL_ADDRESS) >> PDPSHIFT) &
+		i = ((va - KPDPPHYS_KVA) >> PDPSHIFT) &
 		    (NPML4EPG * NPDPEPG - 1);
 		if ((pdp[i] & kernel_pmap->pmap_bits[PG_V_IDX]) == 0)
 			continue;
+		if (is_dumpable(pdp[i] & PG_FRAME) == 0)
+			continue;
 
 		/*
 		 * Add the PD page from the PDP to the dump
@@ -277,7 +279,11 @@
 			/*
 			 * Add the PT page from the PD to the dump (it is no
 			 * longer included in the ptemap.
+			 *
+			 * Do not trust page-table frames at panic time.
 			 */
+			if (is_dumpable(pd[j] & PG_FRAME) == 0)
+				continue;
 			dump_add_page(pd[j] & PG_FRAME);
 			lpdpttl += PAGE_SIZE;
 
@@ -454,6 +460,8 @@
 	int idx, bit;
 
 	pa >>= PAGE_SHIFT;
+	if (pa >= (vm_paddr_t)(vm_page_dump_size / sizeof(*vm_page_dump)) * 64)
+		return;
 	idx = pa >> 6;		/* 2^6 = 64 */
 	bit = pa & 63;
 	atomic_set_long(&vm_page_dump[idx], 1ul << bit);
@@ -465,6 +473,8 @@
 	int idx, bit;
 
 	pa >>= PAGE_SHIFT;
+	if (pa >= (vm_paddr_t)(vm_page_dump_size / sizeof(*vm_page_dump)) * 64)
+		return;
 	idx = pa >> 6;		/* 2^6 = 64 */
 	bit = pa & 63;
 	atomic_clear_long(&vm_page_dump[idx], 1ul << bit);