If the policy plugin does not provide a close function, there is
no command timeout and no pty is required, skip the event loop and just exec the command directly.
This commit is contained in:
37
src/exec.c
37
src/exec.c
@@ -137,35 +137,7 @@ static int fork_cmnd(struct command_details *details, int sv[2])
|
|||||||
close(signal_pipe[0]);
|
close(signal_pipe[0]);
|
||||||
close(signal_pipe[1]);
|
close(signal_pipe[1]);
|
||||||
fcntl(sv[1], F_SETFD, FD_CLOEXEC);
|
fcntl(sv[1], F_SETFD, FD_CLOEXEC);
|
||||||
restore_signals();
|
exec_cmnd(details, &cstat, &sv[1]);
|
||||||
if (exec_setup(details, NULL, -1) == true) {
|
|
||||||
/* headed for execve() */
|
|
||||||
sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
|
|
||||||
details->argv, details->envp);
|
|
||||||
if (details->closefrom >= 0) {
|
|
||||||
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
|
|
||||||
if (ISSET(details->flags, CD_RBAC_ENABLED)) {
|
|
||||||
selinux_execve(details->command, details->argv, details->envp,
|
|
||||||
ISSET(details->flags, CD_NOEXEC));
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
sudo_execve(details->command, details->argv, details->envp,
|
|
||||||
ISSET(details->flags, CD_NOEXEC));
|
|
||||||
}
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
|
|
||||||
details->command, strerror(errno));
|
|
||||||
}
|
|
||||||
cstat.type = CMD_ERRNO;
|
|
||||||
cstat.val = errno;
|
|
||||||
send(sv[1], &cstat, sizeof(cstat), 0);
|
send(sv[1], &cstat, sizeof(cstat), 0);
|
||||||
sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1);
|
sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 1);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
@@ -224,6 +196,11 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
|
|||||||
utmp_user = details->utmp_user ? details->utmp_user : user_details.username;
|
utmp_user = details->utmp_user ? details->utmp_user : user_details.username;
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "allocate pty for I/O logging");
|
sudo_debug_printf(SUDO_DEBUG_INFO, "allocate pty for I/O logging");
|
||||||
pty_setup(details->euid, user_details.tty, utmp_user);
|
pty_setup(details->euid, user_details.tty, utmp_user);
|
||||||
|
} else if (!ISSET(details->flags, CD_SET_TIMEOUT) &&
|
||||||
|
policy_plugin.u.policy->close == NULL) {
|
||||||
|
/* If no I/O logging, timeout or policy close we can exec directly. */
|
||||||
|
exec_cmnd(details, cstat, NULL);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -432,7 +409,7 @@ do_tty_io:
|
|||||||
tq_remove(&sigfwd_list, sigfwd);
|
tq_remove(&sigfwd_list, sigfwd);
|
||||||
efree(sigfwd);
|
efree(sigfwd);
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
|
debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
# include <priv.h>
|
# include <priv.h>
|
||||||
#endif
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
@@ -156,3 +157,44 @@ sudo_execve(const char *path, char *const argv[], char *const envp[], int noexec
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
exec_cmnd(struct command_details *details, struct command_status *cstat,
|
||||||
|
int *errfd)
|
||||||
|
{
|
||||||
|
debug_decl(exec_cmnd, SUDO_DEBUG_EXEC)
|
||||||
|
|
||||||
|
restore_signals();
|
||||||
|
if (exec_setup(details, NULL, -1) == true) {
|
||||||
|
/* headed for execve() */
|
||||||
|
sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
|
||||||
|
details->argv, details->envp);
|
||||||
|
if (details->closefrom >= 0) {
|
||||||
|
int maxfd = details->closefrom;
|
||||||
|
/* Preserve back channel if present. */
|
||||||
|
if (errfd != NULL) {
|
||||||
|
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
|
||||||
|
if (ISSET(details->flags, CD_RBAC_ENABLED)) {
|
||||||
|
selinux_execve(details->command, details->argv, details->envp,
|
||||||
|
ISSET(details->flags, CD_NOEXEC));
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
sudo_execve(details->command, details->argv, details->envp,
|
||||||
|
ISSET(details->flags, CD_NOEXEC));
|
||||||
|
}
|
||||||
|
cstat->type = CMD_ERRNO;
|
||||||
|
cstat->val = errno;
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
|
||||||
|
details->command, strerror(errno));
|
||||||
|
}
|
||||||
|
debug_return;
|
||||||
|
}
|
||||||
|
@@ -98,7 +98,8 @@ 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, int *errfd);
|
static void exec_pty(struct command_details *details,
|
||||||
|
struct command_status *cstat, 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, bool from_parent);
|
static void deliver_signal(pid_t pid, int signo, bool from_parent);
|
||||||
@@ -1077,9 +1078,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, &errpipe[1]);
|
exec_pty(details, &cstat, &errpipe[1]);
|
||||||
cstat.type = CMD_ERRNO;
|
|
||||||
cstat.val = errno;
|
|
||||||
ignore_result(write(errpipe[1], &cstat, sizeof(cstat)));
|
ignore_result(write(errpipe[1], &cstat, sizeof(cstat)));
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
@@ -1283,7 +1282,8 @@ flush_output(void)
|
|||||||
* Returns only if execve() fails.
|
* Returns only if execve() fails.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
exec_pty(struct command_details *details, int *errfd)
|
exec_pty(struct command_details *details,
|
||||||
|
struct command_status *cstat, int *errfd)
|
||||||
{
|
{
|
||||||
pid_t self = getpid();
|
pid_t self = getpid();
|
||||||
debug_decl(exec_pty, SUDO_DEBUG_EXEC);
|
debug_decl(exec_pty, SUDO_DEBUG_EXEC);
|
||||||
@@ -1316,30 +1316,9 @@ exec_pty(struct command_details *details, int *errfd)
|
|||||||
if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
|
if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
|
||||||
close(io_fds[SFD_STDERR]);
|
close(io_fds[SFD_STDERR]);
|
||||||
|
|
||||||
sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
|
/* Execute command; only returns on error. */
|
||||||
details->argv, details->envp);
|
exec_cmnd(details, cstat, errfd);
|
||||||
|
|
||||||
if (details->closefrom >= 0) {
|
|
||||||
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
|
|
||||||
if (ISSET(details->flags, CD_RBAC_ENABLED)) {
|
|
||||||
selinux_execve(details->command, details->argv, details->envp,
|
|
||||||
ISSET(details->flags, CD_NOEXEC));
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
sudo_execve(details->command, details->argv, details->envp,
|
|
||||||
ISSET(details->flags, CD_NOEXEC));
|
|
||||||
}
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
|
|
||||||
details->command, strerror(errno));
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -54,6 +54,8 @@ struct command_status;
|
|||||||
int fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask);
|
int fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask);
|
||||||
int perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat);
|
int perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat);
|
||||||
int suspend_parent(int signo);
|
int suspend_parent(int signo);
|
||||||
|
void exec_cmnd(struct command_details *details, struct command_status *cstat,
|
||||||
|
int *errfd);
|
||||||
void fd_set_iobs(fd_set *fdsr, fd_set *fdsw);
|
void fd_set_iobs(fd_set *fdsr, fd_set *fdsw);
|
||||||
#ifdef SA_SIGINFO
|
#ifdef SA_SIGINFO
|
||||||
void handler(int s, siginfo_t *info, void *context);
|
void handler(int s, siginfo_t *info, void *context);
|
||||||
|
@@ -97,7 +97,7 @@ struct plugin_container {
|
|||||||
};
|
};
|
||||||
TQ_DECLARE(plugin_container)
|
TQ_DECLARE(plugin_container)
|
||||||
|
|
||||||
extern struct plugin_container_list policy_plugins;
|
extern struct plugin_container policy_plugin;
|
||||||
extern struct plugin_container_list io_plugins;
|
extern struct plugin_container_list io_plugins;
|
||||||
|
|
||||||
int sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
|
int sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
|
||||||
|
Reference in New Issue
Block a user