mirror of
https://github.com/sudo-project/sudo.git
synced 2025-09-03 15:55:40 +00:00
Save signal state before changing handlers and restore before
we execute the command.
This commit is contained in:
47
src/exec.c
47
src/exec.c
@@ -128,6 +128,7 @@ static int fork_cmnd(struct command_details *details, char *argv[],
|
|||||||
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();
|
||||||
if (exec_setup(details, NULL, -1) == TRUE) {
|
if (exec_setup(details, NULL, -1) == TRUE) {
|
||||||
/* headed for execve() */
|
/* headed for execve() */
|
||||||
if (details->closefrom >= 0)
|
if (details->closefrom >= 0)
|
||||||
@@ -147,6 +148,52 @@ static int fork_cmnd(struct command_details *details, char *argv[],
|
|||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct signal_state {
|
||||||
|
int signo;
|
||||||
|
sigaction_t sa;
|
||||||
|
} saved_signals[] = {
|
||||||
|
{ SIGALRM },
|
||||||
|
{ SIGCHLD },
|
||||||
|
{ SIGCONT },
|
||||||
|
{ SIGHUP },
|
||||||
|
{ SIGINT },
|
||||||
|
{ SIGPIPE },
|
||||||
|
{ SIGQUIT },
|
||||||
|
{ SIGTERM },
|
||||||
|
{ SIGQUIT },
|
||||||
|
{ SIGTERM },
|
||||||
|
{ SIGTSTP },
|
||||||
|
{ SIGTTIN },
|
||||||
|
{ SIGTTOU },
|
||||||
|
{ SIGUSR1 },
|
||||||
|
{ SIGUSR2 },
|
||||||
|
{ -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save signal handler state so it can be restored before exec.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
save_signals(void)
|
||||||
|
{
|
||||||
|
struct signal_state *ss;
|
||||||
|
|
||||||
|
for (ss = saved_signals; ss->signo != -1; ss++)
|
||||||
|
sigaction(ss->signo, NULL, &ss->sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore signal handlers to initial state.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
restore_signals(void)
|
||||||
|
{
|
||||||
|
struct signal_state *ss;
|
||||||
|
|
||||||
|
for (ss = saved_signals; ss->signo != -1; ss++)
|
||||||
|
sigaction(ss->signo, &ss->sa, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute a command, potentially in a pty with I/O loggging.
|
* Execute a command, potentially in a pty with I/O loggging.
|
||||||
* 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
|
||||||
|
@@ -824,6 +824,7 @@ exec_monitor(struct command_details *details, char *argv[], char *envp[],
|
|||||||
error(1, "cannot create pipe");
|
error(1, "cannot create pipe");
|
||||||
|
|
||||||
/* Reset SIGWINCH and SIGALRM. */
|
/* Reset SIGWINCH and SIGALRM. */
|
||||||
|
/* XXX - restore all signals except SIGPIPE? */
|
||||||
zero_bytes(&sa, sizeof(sa));
|
zero_bytes(&sa, sizeof(sa));
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_RESTART;
|
sa.sa_flags = SA_RESTART;
|
||||||
@@ -885,6 +886,7 @@ exec_monitor(struct command_details *details, char *argv[], char *envp[],
|
|||||||
close(signal_pipe[1]);
|
close(signal_pipe[1]);
|
||||||
close(errpipe[0]);
|
close(errpipe[0]);
|
||||||
fcntl(errpipe[1], F_SETFD, FD_CLOEXEC);
|
fcntl(errpipe[1], F_SETFD, FD_CLOEXEC);
|
||||||
|
restore_signals();
|
||||||
|
|
||||||
/* setup tty and exec command */
|
/* setup tty and exec command */
|
||||||
exec_pty(details, argv, envp);
|
exec_pty(details, argv, envp);
|
||||||
@@ -1082,25 +1084,8 @@ flush_output(void)
|
|||||||
static void
|
static void
|
||||||
exec_pty(struct command_details *details, char *argv[], char *envp[])
|
exec_pty(struct command_details *details, char *argv[], char *envp[])
|
||||||
{
|
{
|
||||||
sigaction_t sa;
|
|
||||||
pid_t self = getpid();
|
pid_t self = getpid();
|
||||||
|
|
||||||
/* Reset signal handlers. */
|
|
||||||
zero_bytes(&sa, sizeof(sa));
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
sa.sa_flags = SA_RESTART;
|
|
||||||
sa.sa_handler = SIG_DFL;
|
|
||||||
sigaction(SIGHUP, &sa, NULL);
|
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
|
||||||
sigaction(SIGINT, &sa, NULL);
|
|
||||||
sigaction(SIGQUIT, &sa, NULL);
|
|
||||||
sigaction(SIGTSTP, &sa, NULL);
|
|
||||||
sigaction(SIGTTIN, &sa, NULL);
|
|
||||||
sigaction(SIGTTOU, &sa, NULL);
|
|
||||||
sigaction(SIGUSR1, &sa, NULL);
|
|
||||||
sigaction(SIGUSR2, &sa, NULL);
|
|
||||||
sigaction(SIGCHLD, &sa, NULL);
|
|
||||||
|
|
||||||
/* Set child process group here too to avoid a race. */
|
/* Set child process group here too to avoid a race. */
|
||||||
setpgid(0, self);
|
setpgid(0, self);
|
||||||
|
|
||||||
|
@@ -167,6 +167,8 @@ void zero_bytes(volatile void *, size_t);
|
|||||||
/* exec.c */
|
/* exec.c */
|
||||||
int sudo_execve(struct command_details *details, char *argv[], char *envp[],
|
int sudo_execve(struct command_details *details, char *argv[], char *envp[],
|
||||||
struct command_status *cstat);
|
struct command_status *cstat);
|
||||||
|
void save_signals(void);
|
||||||
|
void restore_signals(void);
|
||||||
|
|
||||||
/* term.c */
|
/* term.c */
|
||||||
int term_cbreak(int);
|
int term_cbreak(int);
|
||||||
|
Reference in New Issue
Block a user