[BusyBox] mknod issue

Rainer Weikusat rainer.weikusat at sncag.com
Wed Aug 17 19:19:10 UTC 2005


This is the text of the usage message of the busybox mknod tool:

,----
| BusyBox v1.00 (2005.08.08-08:49+0000) multi-call binary
| 
| Usage: mknod [OPTIONS] NAME TYPE MAJOR MINOR
| 
| Create a special file (block, character, or pipe).
| 
| Options:
|         -m      create the special file using the specified mode (default a=rw)
| 
| TYPEs include:
|         b:      Make a block (buffered) device
|         c or u: Make a character (un-buffered) device
|         p:      Make a named pipe. MAJOR and MINOR are ignored for named pipes
`----

The program itself does not behave as indicated by the usage message
for named pipes if major and minor number are specified, but instead
fails and displays the message above. Additionally, the code uses
strchr to search for the 'type' argument in a statically defined array
and doesn't check for the end of the string afterwards, which means
that passing an empty second argument will lead to creation of a named
pipe by accident. The patch below makes the program behave like the
usage message claims it does and causes it to reject empty strings as
type arguments. Additionally, it cleans up the twisted control logic
somehwat and results (at least on the ARM target I am using this for)
in an object file that is 20 bytes smaller than the original version.

Index: busybox/coreutils/mknod.c
===================================================================
RCS file: /data/repo/busybox/coreutils/mknod.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 mknod.c
--- busybox/coreutils/mknod.c	30 Nov 2004 16:02:30 -0000	1.1.1.1
+++ busybox/coreutils/mknod.c	17 Aug 2005 14:56:16 -0000
@@ -29,35 +29,38 @@
 #include "busybox.h"
 #include "libcoreutils/coreutils.h"
 
-static const char modes_chars[] = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 };
-static const mode_t modes_cubp[] = { S_IFIFO, S_IFCHR, S_IFBLK };
+static const char modes_chars[] = { 'p', 'c', 'u', 'b', 0, 1, 1, 2};
+static int type_map[] = { S_IFIFO, S_IFCHR, S_IFCHR, S_IFBLK };
 
-extern int mknod_main(int argc, char **argv)
+int mknod_main(int argc, char **argv)
 {
-	mode_t mode;
-	dev_t dev;
-	const char *name;
+	mode_t mode, type;
+	char const *name;
+	dev_t dev;		/* value is ignored for FIFO and set otherwise */
 
 	mode = getopt_mk_fifo_nod(argc, argv);
-	argv += optind;
 	argc -= optind;
+	
+	if (argc == 4 || argc == 2) {
+		argv += optind;
 
-	if ((argc >= 2) && ((name = strchr(modes_chars, argv[1][0])) != NULL)) {
-		mode |= modes_cubp[(int)(name[4])];
+		name = strchr(modes_chars, argv[1][0]);
+		if (name && *name) {
+			type = type_map[(int)name[4]];
 
-		dev = 0;
-		if ((*name != 'p') && ((argc -= 2) == 2)) {
-			dev = (bb_xgetularg10_bnd(argv[2], 0, 255) << 8)
-				+ bb_xgetularg10_bnd(argv[3], 0, 255);
-		}
-
-		if (argc == 2) {
-			name = *argv;
-			if (mknod(name, mode, dev) == 0) {
-				return EXIT_SUCCESS;
+			if (type != S_IFIFO) {
+				if (argc != 4) goto show_usage;
+				dev = bb_xgetularg10_bnd(argv[2], 0, 255) << 8
+					| bb_xgetularg10_bnd(argv[3], 0, 255);
 			}
-			bb_perror_msg_and_die("%s", name);
+
+			if (mknod(*argv, mode | type, dev) == 0) return EXIT_SUCCESS;
+			
+			bb_perror_msg_and_die("%s", *argv);
 		}
 	}
+
+ show_usage:
 	bb_show_usage();
+	return EXIT_FAILURE;
 }



More information about the busybox mailing list