]> granicus.if.org Git - sudo/commitdiff
Save signal state before changing handlers and restore before
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 2 Feb 2011 19:22:41 +0000 (14:22 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 2 Feb 2011 19:22:41 +0000 (14:22 -0500)
we execute the command.

--HG--
branch : 1.7

exec.c
exec_pty.c
sudo.h

diff --git a/exec.c b/exec.c
index 5b3b3d707442d735c4b7cf314d2198fc9dfeb2e9..d9c3608b035384feec016d4c4500d3b3dc08a56b 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -136,6 +136,7 @@ static int fork_cmnd(path, argv, envp, sv, rbac_enabled)
        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);
@@ -154,6 +155,52 @@ static int fork_cmnd(path, argv, envp, sv, rbac_enabled)
     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
index 4985ff0b281a07e0544d5eab41e4916d90c6ad15..deb685a57a1fbcbbbee205b33041505ec1fe9d7e 100644 (file)
@@ -716,6 +716,7 @@ exec_monitor(path, argv, envp, backchannel, rbac)
        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;
@@ -777,6 +778,7 @@ exec_monitor(path, argv, envp, backchannel, rbac)
        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);
@@ -978,25 +980,8 @@ exec_pty(path, argv, envp, rbac_enabled)
     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);
 
diff --git a/sudo.h b/sudo.h
index fa7e56d9788480d38fb3b796ad3f05d363f6a31d..98e3b3f16c05f8b22a1eb6d76e172f975b46c30e 100644 (file)
--- a/sudo.h
+++ b/sudo.h
@@ -235,6 +235,8 @@ void validate_env_vars      __P((struct list_member *));
 /* 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 *));