⬢ DragonFlyBSD Kernel Audit
DF-5341 / fix.diff
← back to finding ↓ download raw
--- a/sys/platform/pc64/x86_64/mptable.c	2026-10-03 04:37:03.595609252 +0000
+++ b/sys/platform/pc64/x86_64/mptable.c	2026-10-03 04:37:03.627608844 +0000
@@ -498,6 +498,18 @@
 }
 
 static int
+mptable_fps_check(const mpfps_t fps)
+{
+	const u_char *p = (const u_char *)fps;
+	u_int i, sum = 0;
+
+	/* MP spec 4.0: checksum covers the floating pointer structure */
+	for (i = 0; i < sizeof(struct MPFPS); ++i)
+		sum += p[i];
+	return (sum & 0xff);
+}
+
+static int
 mptable_map(struct mptable_pos *mpt)
 {
 	mpfps_t fps = NULL;
@@ -509,12 +521,23 @@
 	bzero(mpt, sizeof(*mpt));
 
 	fps = pmap_mapdev(mptable_fps_phyaddr, sizeof(*fps));
+	if (mptable_fps_check(fps) != 0) {
+		kprintf("MPTABLE: bad MP floating pointer checksum\n");
+		pmap_unmapdev((vm_offset_t)fps, sizeof(*fps));
+		return EINVAL;
+	}
 	if (fps->pap != 0) {
 		/*
 		 * Map configuration table header to get
 		 * the base table size
 		 */
 		cth = pmap_mapdev(fps->pap, sizeof(*cth));
+		if (bcmp(cth->signature, "PCMP", 4) != 0) {
+			kprintf("MPTABLE: bad MP config table signature\n");
+			pmap_unmapdev((vm_offset_t)cth, sizeof(*cth));
+			pmap_unmapdev((vm_offset_t)fps, sizeof(*fps));
+			return EINVAL;
+		}
 		cth_mapsz = cth->base_table_length;
 		pmap_unmapdev((vm_offset_t)cth, sizeof(*cth));