If /dev/tty is not available and no I/O logging plugins are configured,
fall back on exec_nopty() even if the policy plugin requested a pty. We never allocate a pty when sudo is not run from a terminal anyway.
This commit is contained in:
41
src/exec.c
41
src/exec.c
@@ -380,34 +380,37 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have an I/O plugin or the policy plugin has requested one, we
|
* Run the command in a new pty if there is an I/O plugin or the policy
|
||||||
* need to allocate a pty.
|
* has requested a pty. If /dev/tty is unavailable and no I/O plugin
|
||||||
|
* is configured, this returns false and we run the command without a pty.
|
||||||
*/
|
*/
|
||||||
if (!TAILQ_EMPTY(&io_plugins) || ISSET(details->flags, CD_USE_PTY)) {
|
if (!TAILQ_EMPTY(&io_plugins) || ISSET(details->flags, CD_USE_PTY)) {
|
||||||
/*
|
if (exec_pty(details, cstat))
|
||||||
* Run the command in a new pty, wait for it to finish and
|
goto done;
|
||||||
* send the plugin the exit status.
|
}
|
||||||
*/
|
|
||||||
exec_pty(details, cstat);
|
/*
|
||||||
} else if (!ISSET(details->flags, CD_SET_TIMEOUT|CD_SUDOEDIT) &&
|
* If we are not running the command in a pty, we were not invoked
|
||||||
|
* as sudoedit, there is no command timeout and there is no close
|
||||||
|
* function, just exec directly. Only returns on error.
|
||||||
|
*/
|
||||||
|
if (!ISSET(details->flags, CD_SET_TIMEOUT|CD_SUDOEDIT) &&
|
||||||
policy_plugin.u.policy->close == NULL) {
|
policy_plugin.u.policy->close == NULL) {
|
||||||
/*
|
|
||||||
* If we are not running the command in a pty, we were not invoked
|
|
||||||
* as sudoedit, there is no command timeout and there is no close
|
|
||||||
* function, just exec directly. Only returns on error.
|
|
||||||
*/
|
|
||||||
if (!sudo_terminated(cstat)) {
|
if (!sudo_terminated(cstat)) {
|
||||||
exec_cmnd(details, -1);
|
exec_cmnd(details, -1);
|
||||||
cstat->type = CMD_ERRNO;
|
cstat->type = CMD_ERRNO;
|
||||||
cstat->val = errno;
|
cstat->val = errno;
|
||||||
}
|
}
|
||||||
} else {
|
goto done;
|
||||||
/*
|
|
||||||
* No pty but we need to wait for the command to finish to
|
|
||||||
* send the plugin the exit status.
|
|
||||||
*/
|
|
||||||
exec_nopty(details, cstat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Run the command in the existing tty (if any) and wait for it to finish.
|
||||||
|
*/
|
||||||
|
exec_nopty(details, cstat);
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* The caller will run any plugin close functions. */
|
||||||
debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
|
debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -340,7 +340,7 @@ free_exec_closure_nopty(struct exec_closure_nopty *ec)
|
|||||||
/*
|
/*
|
||||||
* Execute a command and wait for it to finish.
|
* Execute a command and wait for it to finish.
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
exec_nopty(struct command_details *details, struct command_status *cstat)
|
exec_nopty(struct command_details *details, struct command_status *cstat)
|
||||||
{
|
{
|
||||||
struct exec_closure_nopty ec = { 0 };
|
struct exec_closure_nopty ec = { 0 };
|
||||||
@@ -371,7 +371,7 @@ exec_nopty(struct command_details *details, struct command_status *cstat)
|
|||||||
/* Check for early termination or suspend signals before we fork. */
|
/* Check for early termination or suspend signals before we fork. */
|
||||||
if (sudo_terminated(cstat)) {
|
if (sudo_terminated(cstat)) {
|
||||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
debug_return_int(0);
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ec.cmnd_pid = sudo_debug_fork();
|
ec.cmnd_pid = sudo_debug_fork();
|
||||||
@@ -436,7 +436,7 @@ exec_nopty(struct command_details *details, struct command_status *cstat)
|
|||||||
|
|
||||||
/* Free things up. */
|
/* Free things up. */
|
||||||
free_exec_closure_nopty(&ec);
|
free_exec_closure_nopty(&ec);
|
||||||
debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1149,7 +1149,7 @@ free_exec_closure_pty(struct exec_closure_pty *ec)
|
|||||||
* This is a little bit tricky due to how POSIX job control works and
|
* This is a little bit tricky due to how POSIX job control works and
|
||||||
* we fact that we have two different controlling terminals to deal with.
|
* we fact that we have two different controlling terminals to deal with.
|
||||||
*/
|
*/
|
||||||
int
|
bool
|
||||||
exec_pty(struct command_details *details, struct command_status *cstat)
|
exec_pty(struct command_details *details, struct command_status *cstat)
|
||||||
{
|
{
|
||||||
int io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } };
|
int io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } };
|
||||||
@@ -1169,6 +1169,9 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|||||||
if (pty_setup(details->euid, user_details.tty)) {
|
if (pty_setup(details->euid, user_details.tty)) {
|
||||||
if (ISSET(details->flags, CD_SET_UTMP))
|
if (ISSET(details->flags, CD_SET_UTMP))
|
||||||
utmp_user = details->utmp_user ? details->utmp_user : user_details.username;
|
utmp_user = details->utmp_user ? details->utmp_user : user_details.username;
|
||||||
|
} else if (TAILQ_EMPTY(&io_plugins)) {
|
||||||
|
/* Not logging I/O and didn't allocate a pty. */
|
||||||
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1332,7 +1335,7 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|||||||
/* Check for early termination or suspend signals before we fork. */
|
/* Check for early termination or suspend signals before we fork. */
|
||||||
if (sudo_terminated(cstat)) {
|
if (sudo_terminated(cstat)) {
|
||||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
debug_return_int(0);
|
debug_return_int(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ec.monitor_pid = sudo_debug_fork();
|
ec.monitor_pid = sudo_debug_fork();
|
||||||
@@ -1422,7 +1425,7 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|||||||
TAILQ_FOREACH_SAFE(sigfwd, &ec.sigfwd_list, entries, sigfwd_next) {
|
TAILQ_FOREACH_SAFE(sigfwd, &ec.sigfwd_list, entries, sigfwd_next) {
|
||||||
free(sigfwd);
|
free(sigfwd);
|
||||||
}
|
}
|
||||||
debug_return_int(cstat->type == CMD_ERRNO ? -1 : 0);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -92,10 +92,10 @@ int sudo_execve(int fd, const char *path, char *const argv[], char *envp[], bool
|
|||||||
char **disable_execute(char *envp[], const char *dso);
|
char **disable_execute(char *envp[], const char *dso);
|
||||||
|
|
||||||
/* exec_nopty.c */
|
/* exec_nopty.c */
|
||||||
int exec_nopty(struct command_details *details, struct command_status *cstat);
|
void exec_nopty(struct command_details *details, struct command_status *cstat);
|
||||||
|
|
||||||
/* exec_pty.c */
|
/* exec_pty.c */
|
||||||
int exec_pty(struct command_details *details, struct command_status *cstat);
|
bool exec_pty(struct command_details *details, struct command_status *cstat);
|
||||||
void pty_cleanup(void);
|
void pty_cleanup(void);
|
||||||
int pty_make_controlling(void);
|
int pty_make_controlling(void);
|
||||||
extern int io_fds[6];
|
extern int io_fds[6];
|
||||||
|
Reference in New Issue
Block a user