2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-03 15:55:40 +00:00

Do not close error pipe or debug fd via closefrom() as we need them

to report an exec error should one occur.
This commit is contained in:
Todd C. Miller
2011-11-29 19:51:24 -05:00
parent 3b2998d554
commit a64f1eaea8
4 changed files with 43 additions and 9 deletions

View File

@@ -398,3 +398,20 @@ sudo_debug_execve2(int level, const char *path, char *const argv[], char *const
sudo_debug_write(buf, buflen); sudo_debug_write(buf, buflen);
free(buf); free(buf);
} }
/*
* Dup sudo_debug_fd to the specified value so we don't
* close it when calling closefrom().
*/
int
sudo_debug_fd_set(int fd)
{
if (sudo_debug_fd != -1 && fd != sudo_debug_fd) {
if (dup2(sudo_debug_fd, fd) == -1)
return -1;
(void)fcntl(fd, F_SETFD, FD_CLOEXEC);
close(sudo_debug_fd);
sudo_debug_fd = fd;
}
return sudo_debug_fd;
}

View File

@@ -180,6 +180,7 @@ extern const char *const sudo_debug_priorities[];
extern const char *const sudo_debug_subsystems[]; extern const char *const sudo_debug_subsystems[];
void sudo_debug_enter(const char *func, const char *file, int line, int subsys); void sudo_debug_enter(const char *func, const char *file, int line, int subsys);
void sudo_debug_execve2(int level, const char *path, char *const argv[], char *const envp[]);
void sudo_debug_exit(const char *func, const char *file, int line, int subsys); void sudo_debug_exit(const char *func, const char *file, int line, int subsys);
void sudo_debug_exit_int(const char *func, const char *file, int line, int subsys, int rval); void sudo_debug_exit_int(const char *func, const char *file, int line, int subsys, int rval);
void sudo_debug_exit_long(const char *func, const char *file, int line, int subsys, long rval); void sudo_debug_exit_long(const char *func, const char *file, int line, int subsys, long rval);
@@ -188,9 +189,9 @@ void sudo_debug_exit_bool(const char *func, const char *file, int line, int subs
void sudo_debug_exit_str(const char *func, const char *file, int line, int subsys, const char *rval); void sudo_debug_exit_str(const char *func, const char *file, int line, int subsys, const char *rval);
void sudo_debug_exit_str_masked(const char *func, const char *file, int line, int subsys, const char *rval); void sudo_debug_exit_str_masked(const char *func, const char *file, int line, int subsys, const char *rval);
void sudo_debug_exit_ptr(const char *func, const char *file, int line, int subsys, const void *rval); void sudo_debug_exit_ptr(const char *func, const char *file, int line, int subsys, const void *rval);
int sudo_debug_fd_set(int fd);
int sudo_debug_init(const char *debugfile, const char *settings); int sudo_debug_init(const char *debugfile, const char *settings);
void sudo_debug_printf2(int level, const char *format, ...) __printflike(2, 3); void sudo_debug_printf2(int level, const char *format, ...) __printflike(2, 3);
void sudo_debug_write(const char *str, int len); void sudo_debug_write(const char *str, int len);
void sudo_debug_execve2(int level, const char *path, char *const argv[], char *const envp[]);
#endif /* _SUDO_DEBUG_H */ #endif /* _SUDO_DEBUG_H */

View File

@@ -136,8 +136,15 @@ static int fork_cmnd(struct command_details *details, int sv[2])
/* headed for execve() */ /* headed for execve() */
sudo_debug_execve(SUDO_DEBUG_INFO, details->command, sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
details->argv, details->envp); details->argv, details->envp);
if (details->closefrom >= 0) if (details->closefrom >= 0) {
closefrom(details->closefrom); int maxfd = details->closefrom;
dup2(sv[1], maxfd);
(void)fcntl(maxfd, F_SETFD, FD_CLOEXEC);
sv[1] = maxfd++;
if (sudo_debug_fd_set(maxfd) != -1)
maxfd++;
closefrom(maxfd);
}
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (ISSET(details->flags, CD_RBAC_ENABLED)) if (ISSET(details->flags, CD_RBAC_ENABLED))
selinux_execve(details->command, details->argv, details->envp); selinux_execve(details->command, details->argv, details->envp);

View File

@@ -101,7 +101,7 @@ static struct io_buffer *iobufs;
static void flush_output(void); static void flush_output(void);
static int exec_monitor(struct command_details *details, int backchannel); static int exec_monitor(struct command_details *details, int backchannel);
static void exec_pty(struct command_details *detail); static void exec_pty(struct command_details *detail, int *errfd);
static void sigwinch(int s); static void sigwinch(int s);
static void sync_ttysize(int src, int dst); static void sync_ttysize(int src, int dst);
static void deliver_signal(pid_t pid, int signo); static void deliver_signal(pid_t pid, int signo);
@@ -936,7 +936,7 @@ exec_monitor(struct command_details *details, int backchannel)
restore_signals(); restore_signals();
/* setup tty and exec command */ /* setup tty and exec command */
exec_pty(details); exec_pty(details, &errpipe[1]);
cstat.type = CMD_ERRNO; cstat.type = CMD_ERRNO;
cstat.val = errno; cstat.val = errno;
if (write(errpipe[1], &cstat, sizeof(cstat)) == -1) if (write(errpipe[1], &cstat, sizeof(cstat)) == -1)
@@ -1137,7 +1137,7 @@ flush_output(void)
* Returns only if execve() fails. * Returns only if execve() fails.
*/ */
static void static void
exec_pty(struct command_details *details) exec_pty(struct command_details *details, int *errfd)
{ {
pid_t self = getpid(); pid_t self = getpid();
debug_decl(exec_pty, SUDO_DEBUG_EXEC); debug_decl(exec_pty, SUDO_DEBUG_EXEC);
@@ -1170,14 +1170,23 @@ exec_pty(struct command_details *details)
sudo_debug_execve(SUDO_DEBUG_INFO, details->command, sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
details->argv, details->envp); details->argv, details->envp);
if (details->closefrom >= 0) if (details->closefrom >= 0) {
closefrom(details->closefrom); int maxfd = details->closefrom;
dup2(*errfd, maxfd);
(void)fcntl(maxfd, F_SETFD, FD_CLOEXEC);
*errfd = maxfd++;
if (sudo_debug_fd_set(maxfd) != -1)
maxfd++;
closefrom(maxfd);
}
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (ISSET(details->flags, CD_RBAC_ENABLED)) if (ISSET(details->flags, CD_RBAC_ENABLED))
selinux_execve(details->command, details->argv, details->envp); selinux_execve(details->command, details->argv, details->envp);
else else
#endif #endif
my_execve(details->command, details->argv, details->envp); my_execve(details->command, details->argv, details->envp);
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
details->command, strerror(errno));
debug_return; debug_return;
} }
@@ -1190,7 +1199,7 @@ sync_ttysize(int src, int dst)
#ifdef TIOCGWINSZ #ifdef TIOCGWINSZ
struct winsize wsize; struct winsize wsize;
pid_t pgrp; pid_t pgrp;
debug_decl(exec_pty, SUDO_DEBUG_EXEC); debug_decl(sync_ttysize, SUDO_DEBUG_EXEC);
if (ioctl(src, TIOCGWINSZ, &wsize) == 0) { if (ioctl(src, TIOCGWINSZ, &wsize) == 0) {
ioctl(dst, TIOCSWINSZ, &wsize); ioctl(dst, TIOCSWINSZ, &wsize);