bin/129405: tcsh vfork bugs

Nate Eldredge neldredge at math.ucsd.edu
Wed Dec 3 16:30:02 PST 2008


>Number:         129405
>Category:       bin
>Synopsis:       tcsh vfork bugs
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 04 00:30:00 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Nate Eldredge
>Release:        7.0-RELEASE
>Organization:
>Environment:
FreeBSD vulcan.lan 7.0-RELEASE-p5 FreeBSD 7.0-RELEASE-p5 #14: Sun Oct  5 11:20:57 PDT 2008     nate at vulcan.lan:/usr/obj/usr/src/sys/VULCAN  amd64
>Description:
tcsh has a number of bugs related to its misuse of vfork().  Currently it uses vfork() when starting subshells; under some conditions these subshells may modify global state before exiting or exec'ing.  These modifications don't make sense in the parent shell (in some cases they include pointers to the subshell's stack) so various bad things happen when the parent returns.

Running tcsh/csh with -F causes it to use fork() instead of vfork().  This is associated with a minor performance penalty, but fixes these problems.

The following PRs are presumably related to this problem, since using -F has been reported to cause them to go away.

bin/41297
bin/52746
bin/125185
amd64/128259
bin/129378

>How-To-Repeat:
See the above mentioned PRs.
>Fix:
As a workaround, run csh with -F.  As a permanent fix, make -F the default.  A patch is attached which does this.  It was made against 7.0-RELEASE-p5 which uses tcsh 6.15.00 but probably will apply to other versions.

I reported this upstream but received no response.

Patch attached with submission follows:

diff -ur tcsh.orig/sh.c src/contrib/tcsh/sh.c
--- tcsh.orig/sh.c	2007-10-16 09:18:39.000000000 -0700
+++ src/contrib/tcsh/sh.c	2008-12-03 16:11:53.000000000 -0800
@@ -89,8 +89,8 @@
 int do_logout = 0;
 #endif /* TESLA */
 
-
-int    use_fork = 0;		/* use fork() instead of vfork()? */
+/* Using vfork() has several bugs, so use fork() instead */
+int    use_fork = 1;		/* use fork() instead of vfork()? */
 
 /*
  * Magic pointer values. Used to specify other invalid conditions aside
@@ -908,9 +908,8 @@
 	    case 'F':
 		/*
 		 * This will cause children to be created using fork instead of
-		 * vfork.
+		 * vfork.  That is now the default, so this has no effect.
 		 */
-		use_fork = 1;
 		break;
 
 	    case ' ':
diff -ur tcsh.orig/tcsh.man src/contrib/tcsh/tcsh.man
--- tcsh.orig/tcsh.man	2008-07-10 10:07:27.000000000 -0700
+++ src/contrib/tcsh/tcsh.man	2008-12-03 16:11:36.000000000 -0800
@@ -133,7 +133,8 @@
 command hashing, and thus starts faster.
 .TP 4
 .B \-F
-The shell uses \fIfork\fR(2) instead of \fIvfork\fR(2) to spawn processes. (+)
+The shell uses \fIfork\fR(2) instead of \fIvfork\fR(2) to spawn processes. 
+This is now the default on FreeBSD so this option has no effect.  (+)
 .TP 4
 .B \-i
 The shell is interactive and prompts for its top-level input, even if


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list