Subject: bin/2975: fsck lies about argv0 to child, so crunch loses
To: None <gnats-bugs@gnats.netbsd.org>
From: VaX#n8 <vax@linkdead.paranoia.com>
List: netbsd-bugs
Date: 11/29/1996 00:17:08
>Number:         2975
>Category:       bin
>Synopsis:       fsck lies about argv0 to child
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Nov 28 23:20:01 1996
>Last-Modified:
>Originator:     VaX#n8
>Organization:
	
League of Non-aligned Wizards
>Release:        <NetBSD-current source date> 16 Nov 1996
>Environment:
	
System: NetBSD linkdead.paranoia.com 1.2B NetBSD 1.2B (LINKDEAD) #0: Sun Nov 17 10:42:34 CST 1996 vax@linkdead.paranoia.com:/usr/src/sys/arch/i386/compile/LINKDEAD i386


>Description:
	
see bin/2974
>How-To-Repeat:
	
see bin/2974
>Fix:
	

I was less ambitious on this one...

--- sbin/fsck/fsck.c~	Mon Oct 14 10:43:41 1996
+++ sbin/fsck/fsck.c	Fri Nov 29 00:09:10 1996
@@ -210,29 +210,34 @@
 	static const char *edirs[] = {
 		_PATH_SBIN,
 		_PATH_USRSBIN,
 		NULL
 	};
+	char execbase[MAXPATHLEN] = "fsck_";
 	const char **argv, **edir;
 	pid_t pid;
-	int argc, i, status, maxargc;
+	int argc = 1, i, status, maxargc;
 	char *optbuf = NULL, execname[MAXPATHLEN + 1];
 	const char *extra = getoptions(vfstype);
 
 #ifdef __GNUC__
 	/* Avoid vfork clobbering */
 	(void) &optbuf;
+	(void) &vfstype;
 #endif
 
 	if (strcmp(vfstype, "ufs") == 0)
 		vfstype = MOUNT_UFS;
 
 	maxargc = 100;
 	argv = emalloc(sizeof(char *) * maxargc);
 
-	argc = 0;
-	argv[argc++] = vfstype;
+	/* construct basename of executable and argv[0] simultaneously */
+	(void)strncat(execbase,
+		     (const char *)vfstype,
+		     sizeof(execbase) - 6); /* strlen("fsck_") + \0 */ 
+	argv[0] = vfstype;
 
 	if (options) {
 		if (extra != NULL)
 			optbuf = catopt(options, extra, 0);
 		else
@@ -246,13 +251,13 @@
 
 	argv[argc++] = spec;
 	argv[argc] = NULL;
 
 	if (flags & (CHECK_DEBUG|CHECK_VERBOSE)) {
-		(void)printf("start %s %swait fsck_%s", mntpt, 
-			pidp ? "no" : "", vfstype);
-		for (i = 1; i < argc; i++)
+		(void)printf("start %s %swait", mntpt, 
+			pidp ? "no" : "");
+		for (i = 0; i < argc; i++)
 			(void)printf(" %s", argv[i]);
 		(void)printf("\n");
 	}
 
 	switch (pid = vfork()) {
@@ -268,11 +273,11 @@
 
 		/* Go find an executable. */
 		edir = edirs;
 		do {
 			(void)snprintf(execname,
-			    sizeof(execname), "%s/fsck_%s", *edir, vfstype);
+			    sizeof(execname), "%s/%s", *edir, execbase);
 			execv(execname, (char * const *)argv);
 			if (errno != ENOENT)
 				if (spec)
 					warn("exec %s for %s", execname, spec);
 				else
@@ -282,11 +287,11 @@
 		if (errno == ENOENT)
 			if (spec)
 				warn("exec %s for %s", execname, spec);
 			else
 				warn("exec %s", execname);
-		exit(1);
+		_exit(1);
 		/* NOTREACHED */
 
 	default:				/* Parent. */
 		if (optbuf)
 			free(optbuf);
>Audit-Trail:
>Unformatted: