Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh Don't leak redirected rescriptors to exec'ed processe...



details:   https://anonhg.NetBSD.org/src/rev/c95659863289
branches:  trunk
changeset: 342661:c95659863289
user:      christos <christos%NetBSD.org@localhost>
date:      Mon Jan 04 03:00:24 2016 +0000

description:
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.

diffstat:

 bin/sh/cd.c    |   6 +++---
 bin/sh/eval.c  |  12 ++++++------
 bin/sh/input.c |   6 +++---
 bin/sh/redir.c |  32 +++++++++++++++++++++-----------
 bin/sh/redir.h |   4 ++--
 5 files changed, 35 insertions(+), 25 deletions(-)

diffs (201 lines):

diff -r 0512642a1f2d -r c95659863289 bin/sh/cd.c
--- a/bin/sh/cd.c       Sun Jan 03 22:05:18 2016 +0000
+++ b/bin/sh/cd.c       Mon Jan 04 03:00:24 2016 +0000
@@ -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 @@
                        (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);
diff -r 0512642a1f2d -r c95659863289 bin/sh/eval.c
--- a/bin/sh/eval.c     Sun Jan 03 22:05:18 2016 +0000
+++ b/bin/sh/eval.c     Mon Jan 04 03:00:24 2016 +0000
@@ -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 @@
                        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 @@
                        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 @@
                        close(pip[0]);
                        if (pip[1] != 1) {
                                close(1);
-                               copyfd(pip[1], 1, 1);
+                               copyfd(pip[1], 1, 1, 0);
                                close(pip[1]);
                        }
                }
diff -r 0512642a1f2d -r c95659863289 bin/sh/input.c
--- a/bin/sh/input.c    Sun Jan 03 22:05:18 2016 +0000
+++ b/bin/sh/input.c    Mon Jan 04 03:00:24 2016 +0000
@@ -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 @@
        }
 
        if (fd < 10) {
-               fd2 = copyfd(fd, 10, 0);
+               fd2 = copyfd(fd, 10, 0, 0);
                close(fd);
                if (fd2 < 0)
                        error("Out of file descriptors");
diff -r 0512642a1f2d -r c95659863289 bin/sh/redir.c
--- a/bin/sh/redir.c    Sun Jan 03 22:05:18 2016 +0000
+++ b/bin/sh/redir.c    Mon Jan 04 03:00:24 2016 +0000
@@ -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 @@
                        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 @@
        }
 
        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 @@
                                 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 @@
  */
 
 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;
diff -r 0512642a1f2d -r c95659863289 bin/sh/redir.h
--- a/bin/sh/redir.h    Sun Jan 03 22:05:18 2016 +0000
+++ b/bin/sh/redir.h    Mon Jan 04 03:00:24 2016 +0000
@@ -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 popredir(void);
 int fd0_redirected_p(void);
 void clearredir(int);
-int copyfd(int, int, int);
+int copyfd(int, int, int, int);
 



Home | Main Index | Thread Index | Old Index