From: Todd C. Miller Date: Tue, 15 Jun 2010 13:05:19 +0000 (-0400) Subject: Check for dup2() failure. X-Git-Tag: SUDO_1_7_3~63 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=061b09c5309be0a4726fd468675b82e91857f2f4;p=sudo Check for dup2() failure. --HG-- branch : 1.7 --- diff --git a/exec_pty.c b/exec_pty.c index 0090394d4..17b0fc62e 100644 --- a/exec_pty.c +++ b/exec_pty.c @@ -986,9 +986,10 @@ exec_pty(path, argv, envp, rbac_enabled) setpgid(0, self); /* Wire up standard fds, note that stdout/stderr may be pipes. */ - dup2(io_fds[SFD_STDIN], STDIN_FILENO); - dup2(io_fds[SFD_STDOUT], STDOUT_FILENO); - dup2(io_fds[SFD_STDERR], STDERR_FILENO); + if (dup2(io_fds[SFD_STDIN], STDIN_FILENO) == -1 || + dup2(io_fds[SFD_STDOUT], STDOUT_FILENO) == -1 || + dup2(io_fds[SFD_STDERR], STDERR_FILENO) == -1) + error(1, "dup2"); /* Wait for parent to grant us the tty if we are foreground. */ if (foreground) { diff --git a/logging.c b/logging.c index c772a1def..ff225fb1e 100644 --- a/logging.c +++ b/logging.c @@ -490,7 +490,7 @@ send_mail(fmt, va_alist) } # endif #endif - chdir("/"); + (void) chdir("/"); if ((fd = open(_PATH_DEVNULL, O_RDWR, 0644)) != -1) { (void) dup2(fd, STDIN_FILENO); (void) dup2(fd, STDOUT_FILENO); @@ -528,12 +528,15 @@ send_mail(fmt, va_alist) /* Child, set stdin to output side of the pipe */ if (pfd[0] != STDIN_FILENO) { - (void) dup2(pfd[0], STDIN_FILENO); + if (dup2(pfd[0], STDIN_FILENO) != -1) { + mysyslog(LOG_ERR, "cannot dup stdin: %m"); + _exit(127); + } (void) close(pfd[0]); } (void) close(pfd[1]); - /* Build up an argv based the mailer path and flags */ + /* Build up an argv based on the mailer path and flags */ mflags = estrdup(def_mailerflags); mpath = estrdup(def_mailerpath); if ((argv[0] = strrchr(mpath, ' '))) diff --git a/selinux.c b/selinux.c index de3c43eeb..8bbd6ebb9 100644 --- a/selinux.c +++ b/selinux.c @@ -114,6 +114,7 @@ relabel_tty(const char *ttyn, int ptyfd) { security_context_t tty_con = NULL; security_context_t new_tty_con = NULL; + int fd; se_state.ttyfd = ptyfd; @@ -162,22 +163,26 @@ relabel_tty(const char *ttyn, int ptyfd) if (se_state.enforcing) goto bad; } - dup2(se_state.ttyfd, ptyfd); + if (dup2(se_state.ttyfd, ptyfd) == -1) { + warning("dup2"); + goto bad; + } } else { /* Re-open tty to get new label and reset std{in,out,err} */ close(se_state.ttyfd); se_state.ttyfd = open(ttyn, O_RDWR|O_NONBLOCK); - if (se_state.ttyfd == -1) + if (se_state.ttyfd == -1) { warning("unable to open %s", ttyn); - else - (void)fcntl(se_state.ttyfd, F_SETFL, - fcntl(se_state.ttyfd, F_GETFL, 0) & ~O_NONBLOCK); - if (isatty(STDIN_FILENO)) - dup2(se_state.ttyfd, STDIN_FILENO); - if (isatty(STDOUT_FILENO)) - dup2(se_state.ttyfd, STDOUT_FILENO); - if (isatty(STDERR_FILENO)) - dup2(se_state.ttyfd, STDERR_FILENO); + goto bad; + } + (void)fcntl(se_state.ttyfd, F_SETFL, + fcntl(se_state.ttyfd, F_GETFL, 0) & ~O_NONBLOCK); + for (fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) { + if (isatty(fd) && dup2(se_state.ttyfd, fd) == -1) { + warning("dup2"); + goto bad; + } + } } /* Retain se_state.ttyfd so we can restore label when command finishes. */ (void)fcntl(se_state.ttyfd, F_SETFD, FD_CLOEXEC); diff --git a/sudo.c b/sudo.c index c54f6a22d..cbc8d0af3 100644 --- a/sudo.c +++ b/sudo.c @@ -1044,16 +1044,16 @@ initial_setup() miss[STDOUT_FILENO] = fcntl(STDOUT_FILENO, F_GETFL, 0) == -1; miss[STDERR_FILENO] = fcntl(STDERR_FILENO, F_GETFL, 0) == -1; if (miss[STDIN_FILENO] || miss[STDOUT_FILENO] || miss[STDERR_FILENO]) { - if ((devnull = open(_PATH_DEVNULL, O_RDWR, 0644)) != -1) { - if (miss[STDIN_FILENO]) - (void) dup2(devnull, STDIN_FILENO); - if (miss[STDOUT_FILENO]) - (void) dup2(devnull, STDOUT_FILENO); - if (miss[STDERR_FILENO]) - (void) dup2(devnull, STDERR_FILENO); - if (devnull > STDERR_FILENO) - close(devnull); - } + if ((devnull = open(_PATH_DEVNULL, O_RDWR, 0644)) == -1) + error(1, "unable to open %s", _PATH_DEVNULL); + if (miss[STDIN_FILENO] && dup2(devnull, STDIN_FILENO) == -1) + error(1, "dup2"); + if (miss[STDOUT_FILENO] && dup2(devnull, STDOUT_FILENO) == -1) + error(1, "dup2"); + if (miss[STDERR_FILENO] && dup2(devnull, STDERR_FILENO) == -1) + error(1, "dup2"); + if (devnull > STDERR_FILENO) + close(devnull); } } diff --git a/tgetpass.c b/tgetpass.c index f0d2a36d3..b8aa25dd9 100644 --- a/tgetpass.c +++ b/tgetpass.c @@ -199,6 +199,10 @@ sudo_askpass(prompt) if (pid == 0) { /* child, point stdout to output side of the pipe and exec askpass */ + if (dup2(pfd[1], STDOUT_FILENO) == -1) { + warning("dup2"); + _exit(255); + } (void) dup2(pfd[1], STDOUT_FILENO); set_perms(PERM_FULL_USER); closefrom(STDERR_FILENO + 1);