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:
@@ -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;
|
||||||
|
}
|
||||||
|
@@ -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 */
|
||||||
|
11
src/exec.c
11
src/exec.c
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user