From a572c95c3b17826b39a6e287fce5b5280b905dfe Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Wed, 15 Aug 2001 11:35:45 +0000 Subject: [PATCH] Don't dump on the label sector or below. This avoids clobbering the label if the dump device overflaps the label (which is a slight misconfiguration). Dump routines don't use dscheck(), so the normal write protection of the label doesn't help. Reduced some nearby overflow bugs. In disk_dumpcheck(), there was (fatal but fail-safe) overflow on i386's with 4GB of memory, at least if Maxmem was the top page (can this happen?). The fix assumes that the sector size divides PAGE_SIZE (dump routines already assume this). In setdumpdev(), the corresponding overflow occurred with only about 2GB of memory on all machines with 32-bit ints. This allowed setdumpdev() to succeed when it shouldn't have, but then disk_dumpcheck() failed safe later. Except in old versions of FreeBSD like RELENG_3 where there is no disk_dumpcheck(). PR: 28164 (label clobbering part) MFC after: 1 week --- sys/kern/kern_shutdown.c | 5 +++-- sys/kern/subr_disk.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index d971ba4ebe27..91f45ab99c89 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -429,8 +430,8 @@ setdumpdev(dev_t dev) /* * XXX should clean up checking in dumpsys() to be more like this. */ - newdumplo = psize - Maxmem * PAGE_SIZE / DEV_BSIZE; - if (newdumplo < 0) + newdumplo = psize - Maxmem * (PAGE_SIZE / DEV_BSIZE); + if (newdumplo <= LABELSECTOR) return (ENOSPC); dumpdev = dev; dumplo = newdumplo; diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 2553bbcc2e18..da961bab3e6e 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -154,8 +154,8 @@ disk_dumpcheck(dev_t dev, u_int *count, u_int *blkno, u_int *secsize) dl = dsgetlabel(dev, dp->d_slice); if (!dl) return (ENXIO); - *count = (u_long)Maxmem * PAGE_SIZE / dl->d_secsize; - if (dumplo < 0 || + *count = Maxmem * (PAGE_SIZE / dl->d_secsize); + if (dumplo <= LABELSECTOR || (dumplo + *count > dl->d_partitions[dkpart(dev)].p_size)) return (EINVAL); boff = dl->d_partitions[dkpart(dev)].p_offset +