diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2012-07-11 13:24:30 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2012-07-11 13:24:30 +0000 |
commit | a6b598222b0526906743ba353219a8c48ff4d382 (patch) | |
tree | 45d34e09120294558f9d81cdd2e775341985f42f /sbin | |
parent | 5a463407f5cb3214ba6fdc821a5aeda3b975ca88 (diff) |
MBR can't handle the truth.
When reading disk size/geometry from disklabel, clamp disk size to
the maximum number of cylinders that fit into UINT32_MAX sectors.
Don't just use the bottom 32 bits of the DL_GETDSIZE(). Warn that
truncation has been done.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/fdisk/disk.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/sbin/fdisk/disk.c b/sbin/fdisk/disk.c index b81da950cdf..9ec4692b7a5 100644 --- a/sbin/fdisk/disk.c +++ b/sbin/fdisk/disk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disk.c,v 1.32 2011/07/05 21:39:09 krw Exp $ */ +/* $OpenBSD: disk.c,v 1.33 2012/07/11 13:24:29 krw Exp $ */ /* * Copyright (c) 1997, 2001 Tobias Weingartner @@ -33,6 +33,7 @@ #include <sys/fcntl.h> #include <sys/ioctl.h> #include <sys/dkio.h> +#include <sys/stdint.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/disklabel.h> @@ -69,6 +70,7 @@ DISK_metrics * DISK_getlabelmetrics(char *name) { DISK_metrics *lm = NULL; + u_int64_t sz, spc; int fd; /* Get label metrics */ @@ -85,7 +87,16 @@ DISK_getlabelmetrics(char *name) lm->cylinders = dl.d_ncylinders; lm->heads = dl.d_ntracks; lm->sectors = dl.d_nsectors; - lm->size = dl.d_secperunit; + /* MBR handles only first UINT32_MAX sectors. */ + spc = (u_int64_t)lm->heads * lm->sectors; + sz = DL_GETDSIZE(&dl); + if (sz > UINT32_MAX) { + lm->cylinders = UINT32_MAX / spc; + lm->size = lm->cylinders * spc; + warnx("disk too large (%llu sectors)." + " size truncated.", sz); + } else + lm->size = sz; unit_types[SECTORS].conversion = dl.d_secsize; } close(fd); |