DF-5341 / fix.diff
--- 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)); |