Bug 86765 - [patch] bsdlabel(8) assigning wrong fs type.
Summary: [patch] bsdlabel(8) assigning wrong fs type.
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: Jaakko Heinonen
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-09-30 18:30 UTC by Alex Lyashkov
Modified: 2010-09-06 16:55 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Lyashkov 2005-09-30 18:30:15 UTC
bsdlabel assing wrong fs type.

Fix: 

don`t know how fix it.
How-To-Repeat: 1. create empty partition
2. run bsdlabel -w -e for create slice and set fs type to 4.4BSD
3. exit with save.
4. run bsdlabel again - look to fs type - it`s changed to SystemV.
5. exit with save. and look bsdlabel write error message about wring FS type.
6. run bsdlabel agen and see fs type assigned to unknow.
Comment 1 Jaakko Heinonen freebsd_committer freebsd_triage 2010-07-02 17:23:18 UTC
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
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2010-07-02 20:30:20 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-fs

New patch submitted.  Although it applies to bin/, perhaps the folks on -fs 
could review it.
Comment 3 Jaakko Heinonen freebsd_committer freebsd_triage 2010-08-09 18:27:20 UTC
Responsible Changed
From-To: freebsd-fs->jh

Take.
Comment 4 dfilter service freebsd_committer freebsd_triage 2010-08-15 18:49:55 UTC
Author: jh
Date: Sun Aug 15 17:49:41 2010
New Revision: 211342
URL: http://svn.freebsd.org/changeset/base/211342

Log:
  - Check that strtoul(3) succeeds to convert the entire string in a few
    places.
  - In getasciilabel(), set the disk type only when a valid type is given.
  
  PR:		bin/86765
  MFC after:	2 weeks

Modified:
  head/sbin/bsdlabel/bsdlabel.c

Modified: head/sbin/bsdlabel/bsdlabel.c
==============================================================================
--- head/sbin/bsdlabel/bsdlabel.c	Sun Aug 15 17:14:05 2010	(r211341)
+++ head/sbin/bsdlabel/bsdlabel.c	Sun Aug 15 17:49:41 2010	(r211342)
@@ -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,11 +794,15 @@ 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);
-			lp->d_type = v;
+			else
+				lp->d_type = v;
 			continue;
 		}
 		if (!strcmp(cp, "flags")) {
@@ -1023,7 +1027,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 +1063,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,
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 5 Jaakko Heinonen freebsd_committer freebsd_triage 2010-08-15 19:04:20 UTC
State Changed
From-To: open->patched

Patched in head (r211342).
Comment 6 dfilter service freebsd_committer freebsd_triage 2010-08-30 15:44:41 UTC
Author: jh
Date: Mon Aug 30 14:44:22 2010
New Revision: 212000
URL: http://svn.freebsd.org/changeset/base/212000

Log:
  MFC r211342:
  
  - Check that strtoul(3) succeeds to convert the entire string in a few
    places.
  - In getasciilabel(), set the disk type only when a valid type is given.
  
  PR:		bin/86765

Modified:
  stable/8/sbin/bsdlabel/bsdlabel.c
Directory Properties:
  stable/8/sbin/bsdlabel/   (props changed)

Modified: stable/8/sbin/bsdlabel/bsdlabel.c
==============================================================================
--- stable/8/sbin/bsdlabel/bsdlabel.c	Mon Aug 30 14:26:02 2010	(r211999)
+++ stable/8/sbin/bsdlabel/bsdlabel.c	Mon Aug 30 14:44:22 2010	(r212000)
@@ -749,7 +749,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];
@@ -788,11 +788,15 @@ 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);
-			lp->d_type = v;
+			else
+				lp->d_type = v;
 			continue;
 		}
 		if (!strcmp(cp, "flags")) {
@@ -1017,7 +1021,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;
 
@@ -1053,9 +1057,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,
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 7 dfilter service freebsd_committer freebsd_triage 2010-09-06 16:48:20 UTC
Author: jh
Date: Mon Sep  6 15:48:06 2010
New Revision: 212258
URL: http://svn.freebsd.org/changeset/base/212258

Log:
  MFC r211342:
  
  - Check that strtoul(3) succeeds to convert the entire string in a few
    places.
  - In getasciilabel(), set the disk type only when a valid type is given.
  
  PR:		bin/86765

Modified:
  stable/7/sbin/bsdlabel/bsdlabel.c
Directory Properties:
  stable/7/sbin/bsdlabel/   (props changed)

Modified: stable/7/sbin/bsdlabel/bsdlabel.c
==============================================================================
--- stable/7/sbin/bsdlabel/bsdlabel.c	Mon Sep  6 13:47:11 2010	(r212257)
+++ stable/7/sbin/bsdlabel/bsdlabel.c	Mon Sep  6 15:48:06 2010	(r212258)
@@ -727,7 +727,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];
@@ -766,11 +766,15 @@ 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);
-			lp->d_type = v;
+			else
+				lp->d_type = v;
 			continue;
 		}
 		if (!strcmp(cp, "flags")) {
@@ -995,7 +999,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;
 
@@ -1031,9 +1035,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,
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 8 Jaakko Heinonen freebsd_committer freebsd_triage 2010-09-06 16:55:38 UTC
State Changed
From-To: patched->closed

Fixed in head, stable/8 and stable/7.