close(signal_pipe[0]);
close(signal_pipe[1]);
fcntl(sv[1], F_SETFD, FD_CLOEXEC);
+ restore_signals();
if (exec_setup(rbac_enabled, user_ttypath, -1) == TRUE) {
/* headed for execve() */
closefrom(def_closefrom);
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.
* This is a little bit tricky due to how POSIX job control works and
error(1, "cannot create pipe");
/* Reset SIGWINCH and SIGALRM. */
+ /* XXX - restore all signals except SIGPIPE? */
zero_bytes(&sa, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
close(signal_pipe[1]);
close(errpipe[0]);
fcntl(errpipe[1], F_SETFD, FD_CLOEXEC);
+ restore_signals();
/* setup tty and exec command */
exec_pty(path, argv, envp, rbac);
char *envp[];
int rbac_enabled;
{
- sigaction_t sa;
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. */
setpgid(0, self);
/* exec.c */
int sudo_execve __P((const char *path, char *argv[], char *envp[], uid_t uid,
struct command_status *cstat, int dowait, int bgmode));
+void save_signals __P((void));
+void restore_signals __P((void));
/* fileops.c */
char *sudo_parseln __P((FILE *));