Module Name:    src
Committed By:   christos
Date:           Mon Jan  4 03:00:24 UTC 2016

Modified Files:
        src/bin/sh: cd.c eval.c input.c redir.c redir.h

Log Message:
Don't leak redirected rescriptors to exec'ed processes. This is what ksh
does, but bash does not. For example:

    $ cat test1
    #!/bin/sh
    exec 6> out
    echo "test" >&6
    sh ./test2
    exec 6>&-
    $ cat test2
    echo "test2" >&6
    $ ./test1
    ./test2: 6: Bad file descriptor

This fixes by side effect the problem of the rc system leaking file descriptors
7 and 8 to all starting daemons:

    $ fstat -p 1359
    USER     CMD          PID   FD MOUNT       INUM MODE         SZ|DV R/W
    root     powerd      1359   wd /              2 drwxr-xr-x     512 r
    root     powerd      1359    0 /          63029 crw-rw-rw-    null rw
    root     powerd      1359    1 /          63029 crw-rw-rw-    null rw
    root     powerd      1359    2 /          63029 crw-rw-rw-    null rw
    root     powerd      1359    3* kqueue pending 0
    root     powerd      1359    4 /          64463 crw-r-----   power r
    root     powerd      1359    7 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
    root     powerd      1359    8 flags 0x80034<ISTTY,MPSAFE,LOCKSWORK,CLEAN>
    root     powerd      1359    9* pipe 0xfffffe815d7bfdc0 -> 0x0 w

Note fd=7,8 pointing to the revoked pty from the parent rc process.


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.45 src/bin/sh/cd.c
cvs rdiff -u -r1.110 -r1.111 src/bin/sh/eval.c
cvs rdiff -u -r1.46 -r1.47 src/bin/sh/input.c
cvs rdiff -u -r1.37 -r1.38 src/bin/sh/redir.c
cvs rdiff -u -r1.16 -r1.17 src/bin/sh/redir.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/sh/cd.c
diff -u src/bin/sh/cd.c:1.44 src/bin/sh/cd.c:1.45
--- src/bin/sh/cd.c:1.44	Wed Aug 31 12:24:54 2011
+++ src/bin/sh/cd.c	Sun Jan  3 22:00:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: cd.c,v 1.44 2011/08/31 16:24:54 plunky Exp $	*/
+/*	$NetBSD: cd.c,v 1.45 2016/01/04 03:00:24 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)cd.c	8.2 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: cd.c,v 1.44 2011/08/31 16:24:54 plunky Exp $");
+__RCSID("$NetBSD: cd.c,v 1.45 2016/01/04 03:00:24 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -429,7 +429,7 @@ find_curdir(int noerror)
 			(void) close(pip[0]);
 			if (pip[1] != 1) {
 				close(1);
-				copyfd(pip[1], 1, 1);
+				copyfd(pip[1], 1, 1, 0);
 				close(pip[1]);
 			}
 			(void) execl("/bin/pwd", "pwd", (char *)0);

Index: src/bin/sh/eval.c
diff -u src/bin/sh/eval.c:1.110 src/bin/sh/eval.c:1.111
--- src/bin/sh/eval.c:1.110	Fri Jan  2 14:56:20 2015
+++ src/bin/sh/eval.c	Sun Jan  3 22:00:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: eval.c,v 1.110 2015/01/02 19:56:20 christos Exp $	*/
+/*	$NetBSD: eval.c,v 1.111 2016/01/04 03:00:24 christos Exp $	*/
 
 /*-
  * Copyright (c) 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)eval.c	8.9 (Berkeley) 6/8/95";
 #else
-__RCSID("$NetBSD: eval.c,v 1.110 2015/01/02 19:56:20 christos Exp $");
+__RCSID("$NetBSD: eval.c,v 1.111 2016/01/04 03:00:24 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -539,14 +539,14 @@ evalpipe(union node *n)
 			INTON;
 			if (prevfd > 0) {
 				close(0);
-				copyfd(prevfd, 0, 1);
+				copyfd(prevfd, 0, 1, 0);
 				close(prevfd);
 			}
 			if (pip[1] >= 0) {
 				close(pip[0]);
 				if (pip[1] != 1) {
 					close(1);
-					copyfd(pip[1], 1, 1);
+					copyfd(pip[1], 1, 1, 0);
 					close(pip[1]);
 				}
 			}
@@ -610,7 +610,7 @@ evalbackcmd(union node *n, struct backcm
 			close(pip[0]);
 			if (pip[1] != 1) {
 				close(1);
-				copyfd(pip[1], 1, 1);
+				copyfd(pip[1], 1, 1, 0);
 				close(pip[1]);
 			}
 			eflag = 0;
@@ -926,7 +926,7 @@ normal_fork:
 			close(pip[0]);
 			if (pip[1] != 1) {
 				close(1);
-				copyfd(pip[1], 1, 1);
+				copyfd(pip[1], 1, 1, 0);
 				close(pip[1]);
 			}
 		}

Index: src/bin/sh/input.c
diff -u src/bin/sh/input.c:1.46 src/bin/sh/input.c:1.47
--- src/bin/sh/input.c:1.46	Wed Oct 30 04:38:40 2013
+++ src/bin/sh/input.c	Sun Jan  3 22:00:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: input.c,v 1.46 2013/10/30 08:38:40 mrg Exp $	*/
+/*	$NetBSD: input.c,v 1.47 2016/01/04 03:00:24 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)input.c	8.3 (Berkeley) 6/9/95";
 #else
-__RCSID("$NetBSD: input.c,v 1.46 2013/10/30 08:38:40 mrg Exp $");
+__RCSID("$NetBSD: input.c,v 1.47 2016/01/04 03:00:24 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -412,7 +412,7 @@ setinputfile(const char *fname, int push
 	}
 
 	if (fd < 10) {
-		fd2 = copyfd(fd, 10, 0);
+		fd2 = copyfd(fd, 10, 0, 0);
 		close(fd);
 		if (fd2 < 0)
 			error("Out of file descriptors");

Index: src/bin/sh/redir.c
diff -u src/bin/sh/redir.c:1.37 src/bin/sh/redir.c:1.38
--- src/bin/sh/redir.c:1.37	Thu Oct 23 17:03:25 2014
+++ src/bin/sh/redir.c	Sun Jan  3 22:00:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: redir.c,v 1.37 2014/10/23 21:03:25 christos Exp $	*/
+/*	$NetBSD: redir.c,v 1.38 2016/01/04 03:00:24 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)redir.c	8.2 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: redir.c,v 1.37 2014/10/23 21:03:25 christos Exp $");
+__RCSID("$NetBSD: redir.c,v 1.38 2016/01/04 03:00:24 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -230,7 +230,8 @@ openredirect(union node *redir, char mem
 			if (memory[redir->ndup.dupfd])
 				memory[fd] = 1;
 			else
-				copyfd(redir->ndup.dupfd, fd, 1);
+				copyfd(redir->ndup.dupfd, fd, 1,
+				    (flags & REDIR_PUSH) == 0);
 		}
 		INTON;
 		return;
@@ -243,9 +244,11 @@ openredirect(union node *redir, char mem
 	}
 
 	if (f != fd) {
-		copyfd(f, fd, 1);
+		copyfd(f, fd, 1, fd > 2);
 		close(f);
-	}
+	} else if (f > 2)
+		(void)fcntl(f, F_SETFD, FD_CLOEXEC);
+
 	INTON;
 	return;
 ecreate:
@@ -316,7 +319,7 @@ popredir(void)
                                 fd0_redirected--;
 			close(i);
 			if (rp->renamed[i] >= 0) {
-				copyfd(rp->renamed[i], i, 1);
+				copyfd(rp->renamed[i], i, 1, 0);
 				close(rp->renamed[i]);
 			}
 		}
@@ -382,14 +385,21 @@ clearredir(int vforked)
  */
 
 int
-copyfd(int from, int to, int equal)
+copyfd(int from, int to, int equal, int cloexec)
 {
 	int newfd;
 
-	if (equal)
-		newfd = dup2(from, to);
-	else
-		newfd = fcntl(from, F_DUPFD, to);
+	if (cloexec && to > 2) {
+	    if (equal)
+		    newfd = dup3(from, to, O_CLOEXEC);
+	    else
+		    newfd = fcntl(from, F_DUPFD_CLOEXEC, to);
+	} else {
+	    if (equal)
+		    newfd = dup2(from, to);
+	    else
+		    newfd = fcntl(from, F_DUPFD, to);
+	}
 	if (newfd < 0) {
 		if (errno == EMFILE)
 			return EMPTY;

Index: src/bin/sh/redir.h
diff -u src/bin/sh/redir.h:1.16 src/bin/sh/redir.h:1.17
--- src/bin/sh/redir.h:1.16	Thu Feb 17 10:13:49 2011
+++ src/bin/sh/redir.h	Sun Jan  3 22:00:24 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: redir.h,v 1.16 2011/02/17 15:13:49 pooka Exp $	*/
+/*	$NetBSD: redir.h,v 1.17 2016/01/04 03:00:24 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -44,5 +44,5 @@ void redirect(union node *, int);
 void popredir(void);
 int fd0_redirected_p(void);
 void clearredir(int);
-int copyfd(int, int, int);
+int copyfd(int, int, int, int);
 

Reply via email to