From kagotani@in.it.okayama-u.ac.jp  Fri Nov 28 02:23:50 1997
Received: from herring.in.it.okayama-u.ac.jp (herring.in.it.okayama-u.ac.jp [150.46.6.41])
          by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id CAA06089
          for <FreeBSD-gnats-submit@freebsd.org>; Fri, 28 Nov 1997 02:23:46 -0800 (PST)
          (envelope-from kagotani@in.it.okayama-u.ac.jp)
Received: by herring.in.it.okayama-u.ac.jp (3.5Wpl6) id TAA05661; Fri, 28 Nov 1997 19:23:33 +0900 (JST)
Message-Id: <199711281023.TAA02509@loach.in.it.okayama-u.ac.jp>
Date: Fri, 28 Nov 1997 19:23:34 +0900 (JST)
From: kagotani@in.it.okayama-u.ac.jp
Reply-To: kagotani@in.it.okayama-u.ac.jp
To: FreeBSD-gnats-submit@freebsd.org
Subject: [2.2.5] /bin/sh dumps core
X-Send-Pr-Version: 3.2

>Number:         5172
>Category:       bin
>Synopsis:       /bin/sh dumps core when exec'ing a bogus script
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 28 02:30:00 PST 1997
>Closed-Date:    Tue Dec 2 02:03:30 PST 1997
>Last-Modified:  Tue Dec  2 02:06:20 PST 1997
>Originator:     Hiroto Kagotani
>Release:        FreeBSD 2.2.5-RELEASE i386
>Organization:
Okayama University, Japan
>Environment:

On the console or on any terminal emulator running any shell.

>Description:

If the interpreter of an executable script does not exist,
and the directory containing the script is not the last part of PATH
variable, then /bin/sh dumps core when exec'int the script.

>How-To-Repeat:

Create two executable scripts named "a" and "b" as follows:

--- a ---
#!/bin/sh
PATH=.:/bin
b
---------
--- b ---
#!/no/such/file
---------

And type "./a" in your shell.  Then, you will get:

% ./a
Segmentation fault - core dumped
%

>Fix:
	
shellexec() in /bin/sh assumes that tryexec() does not change argv[0].
But execve(2) called in tryexec() changes it.
(I'm not sure whether this is a spec or a bug of execve(2).)

So, my sample fix preserves argv[0] before calling execve(2),
and restores it after.

---------
diff -u /usr/src/bin/sh/exec.c ./exec.c
--- /usr/src/bin/sh/exec.c	Mon Aug 25 18:09:46 1997
+++ ./exec.c	Fri Nov 28 18:17:22 1997
@@ -164,6 +164,7 @@
 	char *p;
 #endif
 
+	char *argv0 = argv[0];
 #ifdef SYSV
 	do {
 		execve(cmd, argv, envp);
@@ -171,6 +172,7 @@
 #else
 	execve(cmd, argv, envp);
 #endif
+	argv[0] = argv0;
 	e = errno;
 	if (e == ENOEXEC) {
 		initshellproc();
---------
>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: FreeBSD-gnats-submit@FreeBSD.ORG, kagotani@in.it.okayama-u.ac.jp
Cc:  Subject: Re: bin/5172: [2.2.5] /bin/sh dumps core
Date: Fri, 28 Nov 1997 22:28:39 +1100

 >>Fix:
 >	
 >shellexec() in /bin/sh assumes that tryexec() does not change argv[0].
 >But execve(2) called in tryexec() changes it.
 >(I'm not sure whether this is a spec or a bug of execve(2).)
 
 This is a bug in execve().  It was fixed long ago in -current.  There
 were related bugs when argv[0] is const.  I extracted the diffs for the
 original commit but can't test them in 2.2.x.
 
 Bruce
 
 Index: imgact_shell.c
 ===================================================================
 RCS file: /a/ncvs/src/sys/kern/imgact_shell.c,v
 retrieving revision 1.14
 retrieving revision 1.15
 diff -c -2 -r1.14 -r1.15
 *** imgact_shell.c	1997/02/22 09:38:57	1.14
 --- imgact_shell.c	1997/04/23 22:07:04	1.15
 ***************
 *** 24,28 ****
    * SUCH DAMAGE.
    *
 !  *	$Id: imgact_shell.c,v 1.14 1997/02/22 09:38:57 peter Exp $
    */
   
 --- 24,28 ----
    * SUCH DAMAGE.
    *
 !  *	$Id: imgact_shell.c,v 1.15 1997/04/23 22:07:04 ache Exp $
    */
   
 ***************
 *** 127,132 ****
   	}
   
 ! 	/* set argv[0] to point to original file name */
 ! 	suword(imgp->uap->argv, (int)imgp->uap->fname);
   
   	return(0);
 --- 127,131 ----
   	}
   
 ! 	imgp->argv0 = imgp->uap->fname;
   
   	return(0);
 Index: kern_exec.c
 ===================================================================
 RCS file: /a/ncvs/src/sys/kern/kern_exec.c,v
 retrieving revision 1.62
 retrieving revision 1.63
 diff -c -2 -r1.62 -r1.63
 *** kern_exec.c	1997/04/18 02:43:05	1.62
 --- kern_exec.c	1997/04/23 22:07:05	1.63
 ***************
 *** 24,28 ****
    * SUCH DAMAGE.
    *
 !  *	$Id: kern_exec.c,v 1.62 1997/04/18 02:43:05 davidg Exp $
    */
   
 --- 24,28 ----
    * SUCH DAMAGE.
    *
 !  *	$Id: kern_exec.c,v 1.63 1997/04/23 22:07:05 ache Exp $
    */
   
 ***************
 *** 119,122 ****
 --- 119,123 ----
   	imgp->image_header = NULL;
   	imgp->argc = imgp->envc = 0;
 + 	imgp->argv0 = NULL;
   	imgp->entry_addr = 0;
   	imgp->vmspace_destroyed = 0;
 ***************
 *** 436,453 ****
   
   	if (argv) {
 ! 		while ((argp = (caddr_t) fuword(argv++))) {
 ! 			if (argp == (caddr_t) -1)
 ! 				return (EFAULT);
 ! 			if ((error = copyinstr(argp, imgp->stringp,
 ! 			    imgp->stringspace, &length))) {
 ! 				if (error == ENAMETOOLONG)
 ! 					return(E2BIG);
 ! 				return (error);
 ! 			}
 ! 			imgp->stringspace -= length;
 ! 			imgp->stringp += length;
 ! 			imgp->argc++;
   		}
 ! 	}
   
   	/*
 --- 437,463 ----
   
   	if (argv) {
 ! 		argp = (caddr_t) fuword(argv);
 ! 		if (argp == (caddr_t) -1)
 ! 			return (EFAULT);
 ! 		if (argp)
 ! 			argv++;
 ! 		if (imgp->argv0)
 ! 			argp = imgp->argv0;
 ! 		if (argp) {
 ! 			do {
 ! 				if (argp == (caddr_t) -1)
 ! 					return (EFAULT);
 ! 				if ((error = copyinstr(argp, imgp->stringp,
 ! 				    imgp->stringspace, &length))) {
 ! 					if (error == ENAMETOOLONG)
 ! 						return(E2BIG);
 ! 					return (error);
 ! 				}
 ! 				imgp->stringspace -= length;
 ! 				imgp->stringp += length;
 ! 				imgp->argc++;
 ! 			} while ((argp = (caddr_t) fuword(argv++)));
   		}
 ! 	}	
   
   	/*
 Index: imgact.h
 ===================================================================
 RCS file: /a/ncvs/src/sys/sys/imgact.h,v
 retrieving revision 1.14
 retrieving revision 1.15
 diff -c -r1.14 -r1.15
 *** imgact.h	1997/02/22 09:45:17	1.14
 --- imgact.h	1997/04/23 22:02:37	1.15
 ***************
 *** 30,36 ****
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    * SUCH DAMAGE.
    *
 !  *	$Id: imgact.h,v 1.14 1997/02/22 09:45:17 peter Exp $
    */
   
   #ifndef _SYS_IMGACT_H_
 --- 30,36 ----
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    * SUCH DAMAGE.
    *
 !  *	$Id: imgact.h,v 1.15 1997/04/23 22:02:37 ache Exp $
    */
   
   #ifndef _SYS_IMGACT_H_
 ***************
 *** 46,51 ****
 --- 46,52 ----
   	char *stringp;		/* current 'end' pointer of tmp strings */
   	int stringspace;	/* space left in tmp string storage area */
   	int argc, envc;		/* count of argument and environment strings */
 + 	char *argv0;		/* Replacement for argv[0] when interpreting */
   	unsigned long entry_addr; /* entry address of target executable */
   	char vmspace_destroyed;	/* flag - we've blown away original vm space */
   	char interpreted;	/* flag - this executable is interpreted */
State-Changed-From-To: open->closed 
State-Changed-By: danny 
State-Changed-When: Tue Dec 2 02:03:30 PST 1997 
State-Changed-Why:  

This bug was fixed by bde in -current.  The patches were applied and tested 
against 2.2.5-STABLE, and then committed. 
>Unformatted:
