Subject: Re: disklabeling a 1.7 TB disk
To: David Laight <david@l8s.co.uk>
From: Jun-ichiro itojun Hagino <itojun@iijlab.net>
List: current-users
Date: 02/29/2004 06:43:52
>>On Fri, Feb 27, 2004 at 05:51:31PM -0500, Jan Schaumann wrote:
>>> Ok, I'm going completely insane here. I have a 1.7 TB disk, that I'm
>>> desparately trying to disklabel. So:
>>
>>> cylinders: -869262
>>> total sectors: -876216576
>>
>>printfs now fixed in current.
>>
>>> Ok, so I think: how about I correct the faulty fields? I fix 'total
>>
>>> total sectors: 2147483647
>>
>>This patch should fix disklabel so that it will accept up to 2^32-1
>>for important fields.
>>
>>Going beyond 2^32 sectors is hard.....
>
> btw, NXTNUM/NXTXNUM has problem with _CHECKLINE (_CHECKLINE tries to
> "break" out of the loop, but NXTNUM/NXTXNUM is wrapped by do-while
> so _CHECKLINE does not function correctly.
more error check to strtoul().
itojun
Index: disklabel.c
===================================================================
RCS file: /cvsroot/src/sbin/disklabel/disklabel.c,v
retrieving revision 1.126
diff -u -r1.126 disklabel.c
--- disklabel.c 18 Jan 2004 22:34:22 -0000 1.126
+++ disklabel.c 28 Feb 2004 21:44:12 -0000
@@ -1458,13 +1458,15 @@
continue;
}
if (!strcmp(cp, "total sectors")) {
- v = atoi(tp);
- if (v <= 0) {
+ char *ep;
+ errno = 0;
+ lp->d_secperunit = strtoul(tp, &ep, 10);
+ if (*tp == '\0' || !ep || *ep != '\0' ||
+ errno == ERANGE) {
warnx("line %d: bad %s: %s", lineno, cp, tp);
errors++;
} else
- lp->d_secperunit = v;
- continue;
+ continue;
}
if (!strcmp(cp, "rpm")) {
v = atoi(tp);
@@ -1538,19 +1540,22 @@
break; \
}
-#define NXTNUM(n) do { \
+/* cannot use do-while due to the use of "break" in _CHECKLINE */
+#define NXTNUM(n) { \
_CHECKLINE \
cp = tp, tp = word(cp), (n) = (cp != NULL ? atoi(cp) : 0); \
-} while (/* CONSTCOND */ 0)
+}
-#define NXTXNUM(n) do { \
+/* cannot use do-while due to the use of "break" in _CHECKLINE */
+#define NXTXNUM(n) { \
char *ptr; \
- int m; \
+ u_int32_t m; \
\
_CHECKLINE \
cp = tp, tp = word(cp); \
- m = (int)strtol(cp, &ptr, 10); \
- if (*ptr == '\0') \
+ errno = 0; \
+ m = strtoul(cp, &ptr, 10); \
+ if (*cp && ptr && *ptr == '\0' && errno == 0) \
(n) = m; \
else { \
if (*ptr++ != '/') { \
@@ -1559,32 +1564,27 @@
break; \
} \
(n) = m * lp->d_secpercyl; \
- m = (int)strtol(ptr, &ptr, 10); \
- if (*ptr++ != '/') { \
+ errno = 0; \
+ m = strtoul(ptr, &ptr, 10); \
+ if (!ptr || *ptr++ != '/' || errno == ERANGE) { \
warnx("line %d: invalid format", lineno); \
errors++; \
break; \
} \
(n) += m * lp->d_nsectors; \
- m = (int)strtol(ptr, &ptr, 10); \
+ errno = 0; \
+ m = strtoul(ptr, &ptr, 10); \
+ if (!ptr || *ptr != '\0' || errno == ERANGE) { \
+ warnx("line %d: invalid format", lineno); \
+ errors++; \
+ break; \
+ } \
(n) += m; \
} \
-} while (/* CONSTCOND */ 0)
+}
- NXTXNUM(v);
- if (v < 0) {
- warnx("line %d: bad partition size: %s",
- lineno, cp);
- errors++;
- } else
- pp->p_size = v;
- NXTXNUM(v);
- if (v < 0) {
- warnx("line %d: bad partition offset: %s",
- lineno, cp);
- errors++;
- } else
- pp->p_offset = v;
+ NXTXNUM(pp->p_size);
+ NXTXNUM(pp->p_offset);
/* can't use word() here because of blanks
in fstypenames[] */
_CHECKLINE