Source-Changes-HG archive

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

[src/trunk]: src/bin/sh fix descriptor leaks. PR/47805



details:   https://anonhg.NetBSD.org/src/rev/27d20193dc47
branches:  trunk
changeset: 787664:27d20193dc47
user:      yamt <yamt%NetBSD.org@localhost>
date:      Thu Jun 27 23:22:04 2013 +0000

description:
fix descriptor leaks.  PR/47805

this fix was taken from FreeBSD SVN rev 199953 (Jilles Tjoelker)
    ------------------------------------------------------------------------
    r199953 | jilles | 2009-11-30 07:33:59 +0900 (Mon, 30 Nov 2009) | 16 lines

    Fix some cases where file descriptors from redirections leak to programs.

    - Redirecting fds that were not open before kept two copies of the
      redirected file.
        sh -c '{ :; } 7>/dev/null; fstat -p $$; true'
        (both fd 7 and 10 remained open)
    - File descriptors used to restore things after redirection were not
      set close-on-exec, instead they were explicitly closed before executing
      a program normally and before executing a shell procedure. The latter
      must remain but the former is replaced by close-on-exec.
        sh -c 'exec 7</; { exec fstat -p $$; } 7>/dev/null; true'
        (fd 10 remained open)

    The examples above are simpler than the testsuite because I do not want to
    use fstat or procstat in the testsuite.

diffstat:

 bin/sh/eval.c  |   5 ++---
 bin/sh/redir.c |  27 +++++++++------------------
 2 files changed, 11 insertions(+), 21 deletions(-)

diffs (108 lines):

diff -r d42b009301ae -r 27d20193dc47 bin/sh/eval.c
--- a/bin/sh/eval.c     Thu Jun 27 21:55:10 2013 +0000
+++ b/bin/sh/eval.c     Thu Jun 27 23:22:04 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: eval.c,v 1.106 2013/03/02 22:02:32 christos Exp $      */
+/*     $NetBSD: eval.c,v 1.107 2013/06/27 23:22:04 yamt 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.106 2013/03/02 22:02:32 christos Exp $");
+__RCSID("$NetBSD: eval.c,v 1.107 2013/06/27 23:22:04 yamt Exp $");
 #endif
 #endif /* not lint */
 
@@ -1053,7 +1053,6 @@
 #ifdef DEBUG
                trputs("normal command:  ");  trargs(argv);
 #endif
-               clearredir(vforked);
                redirect(cmd->ncmd.redirect, vforked ? REDIR_VFORK : 0);
                if (!vforked)
                        for (sp = varlist.list ; sp ; sp = sp->next)
diff -r d42b009301ae -r 27d20193dc47 bin/sh/redir.c
--- a/bin/sh/redir.c    Thu Jun 27 21:55:10 2013 +0000
+++ b/bin/sh/redir.c    Thu Jun 27 23:22:04 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: redir.c,v 1.34 2013/06/12 01:36:52 yamt Exp $  */
+/*     $NetBSD: redir.c,v 1.35 2013/06/27 23:22:04 yamt 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.34 2013/06/12 01:36:52 yamt Exp $");
+__RCSID("$NetBSD: redir.c,v 1.35 2013/06/27 23:22:04 yamt Exp $");
 #endif
 #endif /* not lint */
 
@@ -67,6 +67,7 @@
 
 
 #define EMPTY -2               /* marks an unused slot in redirtab */
+#define        CLOSED -1               /* fd was not open before redir */
 #ifndef PIPE_BUF
 # define PIPESIZE 4096         /* amount of buffering in a pipe */
 #else
@@ -109,7 +110,6 @@
        struct redirtab *sv = NULL;
        int i;
        int fd;
-       int try;
        char memory[10];        /* file descriptors to write to memory */
 
        for (i = 10 ; --i >= 0 ; )
@@ -127,41 +127,32 @@
        }
        for (n = redir ; n ; n = n->nfile.next) {
                fd = n->nfile.fd;
-               try = 0;
                if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
                    n->ndup.dupfd == fd)
                        continue; /* redirect from/to same file descriptor */
 
                if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
                        INTOFF;
-again:
                        if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
                                switch (errno) {
                                case EBADF:
-                                       if (!try) {
-                                               openredirect(n, memory, flags);
-                                               try++;
-                                               goto again;
-                                       }
-                                       /* FALLTHROUGH*/
+                                       i = CLOSED;
+                                       break;
                                default:
                                        INTON;
                                        error("%d: %s", fd, strerror(errno));
                                        /* NOTREACHED */
                                }
-                       }
-                       if (!try) {
-                               sv->renamed[fd] = i;
-                               close(fd);
-                       }
+                       } else
+                               (void)fcntl(i, F_SETFD, FD_CLOEXEC);
+                       sv->renamed[fd] = i;
                        INTON;
                } else {
                        close(fd);
                }
                 if (fd == 0)
                         fd0_redirected++;
-               if (!try)
-                       openredirect(n, memory, flags);
+               openredirect(n, memory, flags);
        }
        if (memory[1])
                out1 = &memout;



Home | Main Index | Thread Index | Old Index