bin/86765: bsdlabel(8) assigning wrong fs type.
Jaakko Heinonen
jh at FreeBSD.org
Fri Jul 2 16:30:08 UTC 2010
The following reply was made to PR bin/86765; it has been noted by GNATS.
From: Jaakko Heinonen <jh at FreeBSD.org>
To: bug-followup at FreeBSD.org, shadow at psoft.net
Cc:
Subject: Re: bin/86765: bsdlabel(8) assigning wrong fs type.
Date: Fri, 2 Jul 2010 19:23:18 +0300
I can reproduce this. "4.4BSD" is not a valid file system type but
bsdlabel(8) mishandles it because it doesn't check if strtoul(3)
succeeds to convert the entire string in getasciipartspec((). Thus it
considers "4.4BSD" as 4 which is the type number for "System V". Another
bug is that bsdlabel(8) can't parse file system type names with spaces.
There are four type names with a space defined in sys/disklabel.h.
The patch below seems to fix the reported problem for me but there are
more unchecked strtoul(3) calls which I didn't investigate. Also, it
doesn't fix the problem with spaces in type names.
%%%
Index: sbin/bsdlabel/bsdlabel.c
===================================================================
--- sbin/bsdlabel/bsdlabel.c (revision 209622)
+++ sbin/bsdlabel/bsdlabel.c (working copy)
@@ -755,7 +755,7 @@ word(char *cp)
static int
getasciilabel(FILE *f, struct disklabel *lp)
{
- char *cp;
+ char *cp, *endp;
const char **cpp;
u_int part;
char *tp, line[BUFSIZ];
@@ -794,7 +794,10 @@ getasciilabel(FILE *f, struct disklabel
}
if (cpp < &dktypenames[DKMAXTYPES])
continue;
- v = strtoul(tp, NULL, 10);
+ errno = 0;
+ v = strtoul(tp, &endp, 10);
+ if (errno != 0 || *endp != '\0')
+ v = DKMAXTYPES;
if (v >= DKMAXTYPES)
fprintf(stderr, "line %d:%s %lu\n", lineno,
"Warning, unknown disk type", v);
@@ -1023,7 +1026,7 @@ static int
getasciipartspec(char *tp, struct disklabel *lp, int part, int lineno)
{
struct partition *pp;
- char *cp;
+ char *cp, *endp;
const char **cpp;
u_long v;
@@ -1059,9 +1062,12 @@ getasciipartspec(char *tp, struct diskla
if (*cpp != NULL) {
pp->p_fstype = cpp - fstypenames;
} else {
- if (isdigit(*cp))
- v = strtoul(cp, NULL, 10);
- else
+ if (isdigit(*cp)) {
+ errno = 0;
+ v = strtoul(cp, &endp, 10);
+ if (errno != 0 || *endp != '\0')
+ v = FSMAXTYPES;
+ } else
v = FSMAXTYPES;
if (v >= FSMAXTYPES) {
fprintf(stderr,
%%%
--
Jaakko
More information about the freebsd-bugs
mailing list