From c2f8d24f205648de7a4f81a816542ff201f11f68 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 15 Jun 2010 09:02:23 -0400 Subject: [PATCH] Check for dup2() failure. --- plugins/sudoers/logging.c | 9 ++++++--- src/exec_pty.c | 7 ++++--- src/selinux.c | 27 ++++++++++++++++----------- src/sudo.c | 20 ++++++++++---------- src/tgetpass.c | 5 ++++- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index 92a20c9e9..31e8287a7 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -463,7 +463,7 @@ send_mail(const char *fmt, ...) } # endif #endif - chdir("/"); + (void) chdir("/"); if ((fd = open(_PATH_DEVNULL, O_RDWR, 0644)) != -1) { (void) dup2(fd, STDIN_FILENO); (void) dup2(fd, STDOUT_FILENO); @@ -501,12 +501,15 @@ send_mail(const char *fmt, ...) /* 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/src/exec_pty.c b/src/exec_pty.c index 232da0654..d42109cc2 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -1096,9 +1096,10 @@ exec_pty(struct command_details *details, char *argv[], char *envp[]) 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/src/selinux.c b/src/selinux.c index 3a40d5a3b..c74e9cd02 100644 --- a/src/selinux.c +++ b/src/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/src/sudo.c b/src/sudo.c index 39c148adf..ca6f0c08d 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -271,16 +271,16 @@ fix_fds(void) 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/src/tgetpass.c b/src/tgetpass.c index dfd2a742d..d4abad01b 100644 --- a/src/tgetpass.c +++ b/src/tgetpass.c @@ -222,7 +222,10 @@ sudo_askpass(const char *askpass, const char *prompt) if (pid == 0) { /* child, point stdout to output side of the pipe and exec askpass */ - (void) dup2(pfd[1], STDOUT_FILENO); + if (dup2(pfd[1], STDOUT_FILENO) == -1) { + warning("dup2"); + _exit(255); + } (void) setuid(ROOT_UID); if (setgid(user_details.gid)) { warning("unable to set gid to %u", (unsigned int)user_details.gid); -- 2.40.0