summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2012-07-11 13:24:30 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2012-07-11 13:24:30 +0000
commita6b598222b0526906743ba353219a8c48ff4d382 (patch)
tree45d34e09120294558f9d81cdd2e775341985f42f /sbin
parent5a463407f5cb3214ba6fdc821a5aeda3b975ca88 (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.c15
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);