]> granicus.if.org Git - sudo/commitdiff
Remove extra flag to sudo_sigaction(). We want to trap the signal
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 19 Jan 2013 20:10:01 +0000 (15:10 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 19 Jan 2013 20:10:01 +0000 (15:10 -0500)
regardless of whether or not it is ignored by the underlying command
since there's no way to know what signal handlers the command will
install.  Now we just use sudo_sigaction() to set a flag in
saved_signals[] to indicate whether a signal needs to be restored
before exec.

src/exec.c
src/exec_pty.c
src/signal.c
src/sudo.h

index dd6000b8ee7da1e6ac3b6354021181f279bdbed0..41f7e2f98b2c679c72eb3e8f351981f32696f101 100644 (file)
@@ -113,11 +113,11 @@ static int fork_cmnd(struct command_details *details, int sv[2])
 #else
     sa.sa_handler = handler;
 #endif
-    sudo_sigaction(SIGCONT, &sa, NULL, false);
+    sudo_sigaction(SIGCONT, &sa, NULL);
 #ifdef SA_SIGINFO
     sa.sa_sigaction = handler_user_only;
 #endif
-    sudo_sigaction(SIGTSTP, &sa, NULL, true);
+    sudo_sigaction(SIGTSTP, &sa, NULL);
 
     /*
      * The policy plugin's session init must be run before we fork
@@ -247,12 +247,12 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
 #else
     sa.sa_handler = handler;
 #endif
-    sudo_sigaction(SIGTERM, &sa, NULL, true);
-    sudo_sigaction(SIGALRM, &sa, NULL, false); /* XXX - only if there is a timeout */
-    sudo_sigaction(SIGCHLD, &sa, NULL, false);
-    sudo_sigaction(SIGPIPE, &sa, NULL, false);
-    sudo_sigaction(SIGUSR1, &sa, NULL, true);
-    sudo_sigaction(SIGUSR2, &sa, NULL, true);
+    sudo_sigaction(SIGTERM, &sa, NULL);
+    sudo_sigaction(SIGALRM, &sa, NULL); /* XXX - only if there is a timeout */
+    sudo_sigaction(SIGCHLD, &sa, NULL);
+    sudo_sigaction(SIGPIPE, &sa, NULL);
+    sudo_sigaction(SIGUSR1, &sa, NULL);
+    sudo_sigaction(SIGUSR2, &sa, NULL);
 
     /*
      * When not running the command in a pty, we do not want to
@@ -267,9 +267,9 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
        sa.sa_sigaction = handler_user_only;
     }
 #endif
-    sudo_sigaction(SIGHUP, &sa, NULL, true);
-    sudo_sigaction(SIGINT, &sa, NULL, true);
-    sudo_sigaction(SIGQUIT, &sa, NULL, true);
+    sudo_sigaction(SIGHUP, &sa, NULL);
+    sudo_sigaction(SIGINT, &sa, NULL);
+    sudo_sigaction(SIGQUIT, &sa, NULL);
 
     /* Max fd we will be selecting on. */
     maxfd = MAX(sv[0], signal_pipe[0]);
@@ -514,12 +514,12 @@ dispatch_signals(int sv[2], pid_t child, int log_io, struct command_status *csta
                            sigemptyset(&sa.sa_mask);
                            sa.sa_flags = SA_RESTART;
                            sa.sa_handler = SIG_DFL;
-                           sudo_sigaction(SIGTSTP, &sa, &osa, false);
+                           sudo_sigaction(SIGTSTP, &sa, &osa);
                        }
                        if (kill(getpid(), signo) != 0)
                            warning("kill(%d, SIG%s)", (int)getpid(), signame);
                        if (signo == SIGTSTP)
-                           sudo_sigaction(SIGTSTP, &osa, NULL, false);
+                           sudo_sigaction(SIGTSTP, &osa, NULL);
                        if (fd != -1) {
                            /*
                             * Restore command's process group if different.
@@ -602,7 +602,7 @@ dispatch_pending_signals(struct command_status *cstat)
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = SA_RESTART;
        sa.sa_handler = SIG_DFL;
-       sudo_sigaction(SIGTSTP, &sa, NULL, false);
+       sudo_sigaction(SIGTSTP, &sa, NULL);
        if (kill(getpid(), SIGTSTP) != 0)
            warning("kill(%d, SIGTSTP)", (int)getpid());
        /* No need to reinstall SIGTSTP handler. */
index 42221a5f3f59d6eabc1d4d175c071d9dfabe379a..243012a3359a95a192835552c82ae51ac80254ed 100644 (file)
@@ -380,7 +380,7 @@ suspend_parent(int signo)
            sigemptyset(&sa.sa_mask);
            sa.sa_flags = SA_RESTART;
            sa.sa_handler = SIG_DFL;
-           sudo_sigaction(signo, &sa, &osa, false);
+           sudo_sigaction(signo, &sa, &osa);
        }
        sudo_debug_printf(SUDO_DEBUG_INFO, "kill parent SIG%s", signame);
        if (killpg(ppgrp, signo) != 0)
@@ -413,7 +413,7 @@ suspend_parent(int signo)
        }
 
        if (signo != SIGSTOP)
-           sudo_sigaction(signo, &osa, NULL, false);
+           sudo_sigaction(signo, &osa, NULL);
        rval = ttymode == TERM_RAW ? SIGCONT_FG : SIGCONT_BG;
        break;
     }
@@ -575,7 +575,7 @@ fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask)
     if (io_fds[SFD_USERTTY] != -1) {
        sa.sa_flags = SA_RESTART;
        sa.sa_handler = sigwinch;
-       sudo_sigaction(SIGWINCH, &sa, NULL, false);
+       sudo_sigaction(SIGWINCH, &sa, NULL);
     }
 
     /* So we can block tty-generated signals */
@@ -644,8 +644,8 @@ fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask)
 
     /* We don't want to receive SIGTTIN/SIGTTOU, getting EIO is preferable. */
     sa.sa_handler = SIG_IGN;
-    sudo_sigaction(SIGTTIN, &sa, NULL, true);
-    sudo_sigaction(SIGTTOU, &sa, NULL, true);
+    sudo_sigaction(SIGTTIN, &sa, NULL);
+    sudo_sigaction(SIGTTOU, &sa, NULL);
 
     /* Job control signals to relay from parent to child. */
     sigfillset(&sa.sa_mask);
@@ -656,7 +656,7 @@ fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask)
 #else
     sa.sa_handler = handler;
 #endif
-    sudo_sigaction(SIGTSTP, &sa, NULL, true);
+    sudo_sigaction(SIGTSTP, &sa, NULL);
 
     if (foreground) {
        /* Copy terminal attrs from user tty -> pty slave. */
@@ -991,13 +991,13 @@ exec_monitor(struct command_details *details, int backchannel)
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_RESTART;
     sa.sa_handler = SIG_DFL;
-    sudo_sigaction(SIGWINCH, &sa, NULL, false);
-    sudo_sigaction(SIGALRM, &sa, NULL, false); /* XXX - saved value */
+    sudo_sigaction(SIGWINCH, &sa, NULL);
+    sudo_sigaction(SIGALRM, &sa, NULL);
 
     /* Ignore any SIGTTIN or SIGTTOU we get. */
     sa.sa_handler = SIG_IGN;
-    sudo_sigaction(SIGTTIN, &sa, NULL, true);
-    sudo_sigaction(SIGTTOU, &sa, NULL, true);
+    sudo_sigaction(SIGTTIN, &sa, NULL);
+    sudo_sigaction(SIGTTOU, &sa, NULL);
 
     /* Block all signals in mon_handler(). */
     sigfillset(&sa.sa_mask);
@@ -1010,7 +1010,7 @@ exec_monitor(struct command_details *details, int backchannel)
 #else
     sa.sa_handler = mon_handler;
 #endif
-    sudo_sigaction(SIGCHLD, &sa, NULL, false);
+    sudo_sigaction(SIGCHLD, &sa, NULL);
 
     /* Catch common signals so we can cleanup properly. */
     sa.sa_flags = SA_RESTART;
@@ -1020,13 +1020,13 @@ exec_monitor(struct command_details *details, int backchannel)
 #else
     sa.sa_handler = mon_handler;
 #endif
-    sudo_sigaction(SIGHUP, &sa, NULL, true);
-    sudo_sigaction(SIGINT, &sa, NULL, true);
-    sudo_sigaction(SIGQUIT, &sa, NULL, true);
-    sudo_sigaction(SIGTERM, &sa, NULL, true);
-    sudo_sigaction(SIGTSTP, &sa, NULL, true);
-    sudo_sigaction(SIGUSR1, &sa, NULL, true);
-    sudo_sigaction(SIGUSR2, &sa, NULL, true);
+    sudo_sigaction(SIGHUP, &sa, NULL);
+    sudo_sigaction(SIGINT, &sa, NULL);
+    sudo_sigaction(SIGQUIT, &sa, NULL);
+    sudo_sigaction(SIGTERM, &sa, NULL);
+    sudo_sigaction(SIGTSTP, &sa, NULL);
+    sudo_sigaction(SIGUSR1, &sa, NULL);
+    sudo_sigaction(SIGUSR2, &sa, NULL);
 
     /*
      * Start a new session with the parent as the session leader
index 549279637d984616839b9210aa6f883707b7c2db..522e76d2ab85a8f8f719a3cc89fbdce81e298ade 100644 (file)
@@ -44,6 +44,7 @@ int signal_pipe[2];
 
 static struct signal_state {
     int signo;
+    int restore;
     sigaction_t sa;
 } saved_signals[] = {
     { SIGALRM },       /* SAVED_SIGALRM */
@@ -86,8 +87,10 @@ restore_signals(void)
     struct signal_state *ss;
     debug_decl(restore_signals, SUDO_DEBUG_MAIN)
 
-    for (ss = saved_signals; ss->signo != -1; ss++)
-       sigaction(ss->signo, &ss->sa, NULL);
+    for (ss = saved_signals; ss->signo != -1; ss++) {
+       if (ss->restore)
+           sigaction(ss->signo, &ss->sa, NULL);
+    }
 
     debug_return;
 }
@@ -146,22 +149,28 @@ init_signals(void)
 }
 
 /*
- * Like sigaction() but includes an udpate_only flag.
- * In update-only mode, don't override SIG_IGN.
+ * Like sigaction() but sets restore flag in saved_signals[]
+ * if needed.
  */
 int
-sudo_sigaction(int signo, struct sigaction *sa, struct sigaction *osa, bool update_only)
+sudo_sigaction(int signo, struct sigaction *sa, struct sigaction *osa)
 {
-    /* Don't override SIG_IGN if the update_only flag is set. */
-    if (update_only) {
-       struct signal_state *ss;
-       for (ss = saved_signals; ss->signo > 0; ss++) {
-           if (ss->signo == signo) {
-               if (ss->sa.sa_handler == SIG_IGN)
-                   return 0;
-               break;
+    struct signal_state *ss;
+    int rval;
+    debug_decl(sudo_sigaction, SUDO_DEBUG_MAIN)
+
+    for (ss = saved_signals; ss->signo > 0; ss++) {
+       if (ss->signo == signo) {
+           /* If signal was or now is ignored, restore old handler on exec. */
+           if (ss->sa.sa_handler == SIG_IGN || sa->sa_handler == SIG_IGN) {
+               sudo_debug_printf(SUDO_DEBUG_INFO,
+                   "will restore signal %d on exec", signo);
+               ss->restore = true;
            }
+           break;
        }
     }
-    return sigaction(signo, sa, osa);
+    rval = sigaction(signo, sa, osa);
+
+    debug_return_int(rval);
 }
index 1517b560f2681925a02e22f6a37b066dc32d473c..492f19518444031c46423d12a603f9ce194c5646 100644 (file)
@@ -267,7 +267,7 @@ char *get_process_ttyname(void);
 /* signal.c */
 struct sigaction;
 extern int signal_pipe[2];
-int sudo_sigaction(int signo, struct sigaction *sa, struct sigaction *osa, bool update_only);
+int sudo_sigaction(int signo, struct sigaction *sa, struct sigaction *osa);
 void init_signals(void);
 void restore_signals(void);
 void save_signals(void);