]> granicus.if.org Git - sudo/commitdiff
Move signal code into its own source file and add sudo_sigaction()
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 17 Jan 2013 18:29:46 +0000 (13:29 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 17 Jan 2013 18:29:46 +0000 (13:29 -0500)
wrapper that has an extra flag to check the saved_signals list to
only install the handler if the signal is not already ignored.
Bump plugin API version for the new front-end signal behavior.

MANIFEST
include/sudo_plugin.h
src/Makefile.in
src/exec.c
src/exec_pty.c
src/signal.c [new file with mode: 0644]
src/sudo.c
src/sudo.h

index 48454ecac0261cf27fd54140ba47d88fbdcc2fe4..aeb9661d60a0daf9bf64b98b18e9c1e3c1558818 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -347,6 +347,7 @@ src/po/zh_CN.po
 src/preload.c
 src/selinux.c
 src/sesh.c
+src/signal.c
 src/solaris.c
 src/sudo.c
 src/sudo.h
index 52dee0adf6bb108e3a4c26b744f42c6d861b6a02..7a2e3b6fbc41ba3e99d19ed30722c092235e3f6a 100644 (file)
@@ -19,7 +19,7 @@
 
 /* API version major/minor */
 #define SUDO_API_VERSION_MAJOR 1
-#define SUDO_API_VERSION_MINOR 2
+#define SUDO_API_VERSION_MINOR 3
 #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
 #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
 
index 8b2474d9f8b3d447e0d0ff383941f96541fde75e..261afd937beb40d5b072d0c0df9c1e0dea9f8a92 100644 (file)
@@ -85,8 +85,8 @@ SHELL = @SHELL@
 PROGS = @PROGS@
 
 OBJS = conversation.o env_hooks.o exec.o exec_common.o exec_pty.o get_pty.o \
-       hooks.o net_ifs.o load_plugins.o parse_args.o sudo.o sudo_edit.o \
-       tgetpass.o ttyname.o utmp.o @SUDO_OBJS@
+       hooks.o net_ifs.o load_plugins.o parse_args.o signal.o sudo.o \
+       sudo_edit.o tgetpass.o ttyname.o utmp.o @SUDO_OBJS@
 
 SESH_OBJS = sesh.o locale_stub.o exec_common.o
 
@@ -261,6 +261,12 @@ sesh.o: $(srcdir)/sesh.c $(top_builddir)/config.h \
         $(incdir)/list.h $(incdir)/sudo_debug.h $(srcdir)/sudo_exec.h \
         $(incdir)/sudo_plugin.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sesh.c
+signal.o: $(srcdir)/signal.c $(top_builddir)/config.h $(srcdir)/sudo.h \
+          $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
+          $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
+          $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
+          $(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/signal.c
 solaris.o: $(srcdir)/solaris.c $(top_builddir)/config.h $(srcdir)/sudo.h \
            $(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
            $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
index 11ab6ac18091110b0798e835b35e9e3016918f5b..dd6000b8ee7da1e6ac3b6354021181f279bdbed0 100644 (file)
@@ -104,7 +104,7 @@ static int fork_cmnd(struct command_details *details, int sv[2])
      * XXX - currently we send SIGCONT upon resume in some cases where
      * we don't need to (e.g. command pgrp == parent pgrp).
      */
-    zero_bytes(&sa, sizeof(sa));
+    memset(&sa, 0, sizeof(sa));
     sigfillset(&sa.sa_mask);
     sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
 #ifdef SA_SIGINFO
@@ -113,11 +113,11 @@ static int fork_cmnd(struct command_details *details, int sv[2])
 #else
     sa.sa_handler = handler;
 #endif
-    sigaction(SIGCONT, &sa, NULL);
+    sudo_sigaction(SIGCONT, &sa, NULL, false);
 #ifdef SA_SIGINFO
     sa.sa_sigaction = handler_user_only;
 #endif
-    sigaction(SIGTSTP, &sa, NULL);
+    sudo_sigaction(SIGTSTP, &sa, NULL, true);
 
     /*
      * The policy plugin's session init must be run before we fork
@@ -175,56 +175,6 @@ static int fork_cmnd(struct command_details *details, int sv[2])
     debug_return_int(cmnd_pid);
 }
 
-static struct signal_state {
-    int signo;
-    sigaction_t sa;
-} saved_signals[] = {
-    { SIGALRM },       /* SAVED_SIGALRM */
-    { SIGCHLD },       /* SAVED_SIGCHLD */
-    { SIGCONT },       /* SAVED_SIGCONT */
-    { SIGHUP },                /* SAVED_SIGHUP */
-    { SIGINT },                /* SAVED_SIGINT */
-    { SIGPIPE },       /* SAVED_SIGPIPE */
-    { SIGQUIT },       /* SAVED_SIGQUIT */
-    { SIGTERM },       /* SAVED_SIGTERM */
-    { SIGTSTP },       /* SAVED_SIGTSTP */
-    { SIGTTIN },       /* SAVED_SIGTTIN */
-    { SIGTTOU },       /* SAVED_SIGTTOU */
-    { SIGUSR1 },       /* SAVED_SIGUSR1 */
-    { SIGUSR2 },       /* SAVED_SIGUSR2 */
-    { -1 }
-};
-
-/*
- * Save signal handler state so it can be restored before exec.
- */
-void
-save_signals(void)
-{
-    struct signal_state *ss;
-    debug_decl(save_signals, SUDO_DEBUG_EXEC)
-
-    for (ss = saved_signals; ss->signo != -1; ss++)
-       sigaction(ss->signo, NULL, &ss->sa);
-
-    debug_return;
-}
-
-/*
- * Restore signal handlers to initial state.
- */
-void
-restore_signals(void)
-{
-    struct signal_state *ss;
-    debug_decl(restore_signals, SUDO_DEBUG_EXEC)
-
-    for (ss = saved_signals; ss->signo != -1; ss++)
-       sigaction(ss->signo, &ss->sa, NULL);
-
-    debug_return;
-}
-
 /*
  * 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
@@ -288,7 +238,7 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
      * We block all other signals while running the signal handler.
      * Note: HP-UX select() will not be interrupted if SA_RESTART set.
      */
-    zero_bytes(&sa, sizeof(sa));
+    memset(&sa, 0, sizeof(sa));
     sigfillset(&sa.sa_mask);
     sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
 #ifdef SA_SIGINFO
@@ -297,12 +247,12 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
 #else
     sa.sa_handler = handler;
 #endif
-    sigaction(SIGALRM, &sa, NULL);
-    sigaction(SIGCHLD, &sa, NULL);
-    sigaction(SIGPIPE, &sa, NULL);
-    sigaction(SIGTERM, &sa, NULL);
-    sigaction(SIGUSR1, &sa, NULL);
-    sigaction(SIGUSR2, &sa, NULL);
+    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);
 
     /*
      * When not running the command in a pty, we do not want to
@@ -317,9 +267,9 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
        sa.sa_sigaction = handler_user_only;
     }
 #endif
-    sigaction(SIGHUP, &sa, NULL);
-    sigaction(SIGINT, &sa, NULL);
-    sigaction(SIGQUIT, &sa, NULL);
+    sudo_sigaction(SIGHUP, &sa, NULL, true);
+    sudo_sigaction(SIGINT, &sa, NULL, true);
+    sudo_sigaction(SIGQUIT, &sa, NULL, true);
 
     /* Max fd we will be selecting on. */
     maxfd = MAX(sv[0], signal_pipe[0]);
@@ -560,15 +510,16 @@ dispatch_signals(int sv[2], pid_t child, int log_io, struct command_status *csta
                                saved_pgrp = -1;
                        }
                        if (signo == SIGTSTP) {
-                           zero_bytes(&sa, sizeof(sa));
+                           memset(&sa, 0, sizeof(sa));
                            sigemptyset(&sa.sa_mask);
+                           sa.sa_flags = SA_RESTART;
                            sa.sa_handler = SIG_DFL;
-                           sigaction(SIGTSTP, &sa, &osa);
+                           sudo_sigaction(SIGTSTP, &sa, &osa, false);
                        }
                        if (kill(getpid(), signo) != 0)
                            warning("kill(%d, SIG%s)", (int)getpid(), signame);
                        if (signo == SIGTSTP)
-                           sigaction(SIGTSTP, &osa, NULL);
+                           sudo_sigaction(SIGTSTP, &osa, NULL, false);
                        if (fd != -1) {
                            /*
                             * Restore command's process group if different.
@@ -603,7 +554,7 @@ dispatch_signals(int sv[2], pid_t child, int log_io, struct command_status *csta
 }
 
 /*
- * Read pending signals on signale_pipe written by sudo_handler().
+ * Drain pending signals from signale_pipe written by sudo_handler().
  * Handles the case where the signal was sent to us before
  * we have executed the command.
  * Returns 1 if we should terminate, else 0.
@@ -647,10 +598,11 @@ dispatch_pending_signals(struct command_status *cstat)
     /* Only stop if we haven't already been terminated. */
     if (signo == SIGTSTP)
     {
-       zero_bytes(&sa, sizeof(sa));
+       memset(&sa, 0, sizeof(sa));
        sigemptyset(&sa.sa_mask);
+       sa.sa_flags = SA_RESTART;
        sa.sa_handler = SIG_DFL;
-       sigaction(SIGTSTP, &sa, NULL);
+       sudo_sigaction(SIGTSTP, &sa, NULL, false);
        if (kill(getpid(), SIGTSTP) != 0)
            warning("kill(%d, SIGTSTP)", (int)getpid());
        /* No need to reinstall SIGTSTP handler. */
index d0601102cc24f33389246a2ee2c482f914e04535..42221a5f3f59d6eabc1d4d175c071d9dfabe379a 100644 (file)
@@ -376,11 +376,11 @@ suspend_parent(int signo)
 
        /* Suspend self and continue command when we resume. */
        if (signo != SIGSTOP) {
-           zero_bytes(&sa, sizeof(sa));
+           memset(&sa, 0, sizeof(sa));
            sigemptyset(&sa.sa_mask);
-           sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */
+           sa.sa_flags = SA_RESTART;
            sa.sa_handler = SIG_DFL;
-           sigaction(signo, &sa, &osa);
+           sudo_sigaction(signo, &sa, &osa, false);
        }
        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)
-           sigaction(signo, &osa, NULL);
+           sudo_sigaction(signo, &osa, NULL, false);
        rval = ttymode == TERM_RAW ? SIGCONT_FG : SIGCONT_BG;
        break;
     }
@@ -569,13 +569,13 @@ fork_pty(struct command_details *details, int sv[], int *maxfd, sigset_t *omask)
 
     ppgrp = getpgrp(); /* parent's pgrp, so child can signal us */
 
-    zero_bytes(&sa, sizeof(sa));
+    memset(&sa, 0, sizeof(sa));
     sigemptyset(&sa.sa_mask);
 
     if (io_fds[SFD_USERTTY] != -1) {
        sa.sa_flags = SA_RESTART;
        sa.sa_handler = sigwinch;
-       sigaction(SIGWINCH, &sa, NULL);
+       sudo_sigaction(SIGWINCH, &sa, NULL, false);
     }
 
     /* 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;
-    sigaction(SIGTTIN, &sa, NULL);
-    sigaction(SIGTTOU, &sa, NULL);
+    sudo_sigaction(SIGTTIN, &sa, NULL, true);
+    sudo_sigaction(SIGTTOU, &sa, NULL, true);
 
     /* 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
-    sigaction(SIGTSTP, &sa, NULL);
+    sudo_sigaction(SIGTSTP, &sa, NULL, true);
 
     if (foreground) {
        /* Copy terminal attrs from user tty -> pty slave. */
@@ -987,17 +987,17 @@ exec_monitor(struct command_details *details, int backchannel)
        error(1, _("unable to create pipe"));
 
     /* Reset SIGWINCH and SIGALRM. */
-    zero_bytes(&sa, sizeof(sa));
+    memset(&sa, 0, sizeof(sa));
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_RESTART;
     sa.sa_handler = SIG_DFL;
-    sigaction(SIGWINCH, &sa, NULL);
-    sigaction(SIGALRM, &sa, NULL);
+    sudo_sigaction(SIGWINCH, &sa, NULL, false);
+    sudo_sigaction(SIGALRM, &sa, NULL, false); /* XXX - saved value */
 
     /* Ignore any SIGTTIN or SIGTTOU we get. */
     sa.sa_handler = SIG_IGN;
-    sigaction(SIGTTIN, &sa, NULL);
-    sigaction(SIGTTOU, &sa, NULL);
+    sudo_sigaction(SIGTTIN, &sa, NULL, true);
+    sudo_sigaction(SIGTTOU, &sa, NULL, true);
 
     /* 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
-    sigaction(SIGCHLD, &sa, NULL);
+    sudo_sigaction(SIGCHLD, &sa, NULL, false);
 
     /* 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
-    sigaction(SIGHUP, &sa, NULL);
-    sigaction(SIGINT, &sa, NULL);
-    sigaction(SIGQUIT, &sa, NULL);
-    sigaction(SIGTERM, &sa, NULL);
-    sigaction(SIGTSTP, &sa, NULL);
-    sigaction(SIGUSR1, &sa, NULL);
-    sigaction(SIGUSR2, &sa, NULL);
+    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);
 
     /*
      * Start a new session with the parent as the session leader
diff --git a/src/signal.c b/src/signal.c
new file mode 100644 (file)
index 0000000..5492796
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <errno.h>
+#include <signal.h>
+
+#include "sudo.h"
+
+int signal_pipe[2];
+
+static struct signal_state {
+    int signo;
+    sigaction_t sa;
+} saved_signals[] = {
+    { SIGALRM },       /* SAVED_SIGALRM */
+    { SIGCHLD },       /* SAVED_SIGCHLD */
+    { SIGCONT },       /* SAVED_SIGCONT */
+    { SIGHUP },                /* SAVED_SIGHUP */
+    { SIGINT },                /* SAVED_SIGINT */
+    { SIGPIPE },       /* SAVED_SIGPIPE */
+    { SIGQUIT },       /* SAVED_SIGQUIT */
+    { SIGTERM },       /* SAVED_SIGTERM */
+    { SIGTSTP },       /* SAVED_SIGTSTP */
+    { SIGTTIN },       /* SAVED_SIGTTIN */
+    { SIGTTOU },       /* SAVED_SIGTTOU */
+    { SIGUSR1 },       /* SAVED_SIGUSR1 */
+    { SIGUSR2 },       /* SAVED_SIGUSR2 */
+    { -1 }
+};
+
+/*
+ * Save signal handler state so it can be restored before exec.
+ */
+void
+save_signals(void)
+{
+    struct signal_state *ss;
+    debug_decl(save_signals, SUDO_DEBUG_MAIN)
+
+    for (ss = saved_signals; ss->signo != -1; ss++)
+       sigaction(ss->signo, NULL, &ss->sa);
+
+    debug_return;
+}
+
+/*
+ * Restore signal handlers to initial state for exec.
+ */
+void
+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);
+
+    debug_return;
+}
+
+static void
+sudo_handler(int signo)
+{
+    /*
+     * The pipe is non-blocking, if we overflow the kernel's pipe
+     * buffer we drop the signal.  This is not a problem in practice.
+     */
+    ignore_result(write(signal_pipe[1], &signo, sizeof(signo)));
+}
+
+/*
+ * Trap tty-generated (and other) signals so we can't be killed before
+ * calling the policy close function.  The signal pipe will be drained
+ * in sudo_execute() before running the command and new handlers will
+ * be installed in the parent.
+ */
+void
+init_signals(void)
+{
+    struct sigaction sa;
+    struct signal_state *ss;
+    debug_decl(init_signals, SUDO_DEBUG_MAIN)
+
+    /*
+     * We use a pipe to atomically handle signal notification within
+     * the select() loop without races (we may not have pselect()).
+     */
+    if (pipe_nonblock(signal_pipe) != 0)
+       error(1, _("unable to create pipe"));
+
+    memset(&sa, 0, sizeof(sa));
+    sigfillset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART;
+    sa.sa_handler = sudo_handler;
+
+    for (ss = saved_signals; ss->signo > 0; ss++) {
+       switch (ss->signo) {
+           case SIGCHLD:
+           case SIGCONT:
+           case SIGPIPE:
+           case SIGTTIN:
+           case SIGTTOU:
+               /* Don't install these until exec time. */
+               break;
+           default:
+               if (ss->sa.sa_handler != SIG_IGN)
+                   sigaction(ss->signo, &sa, NULL);
+               break;
+       }
+    }
+    debug_return;
+}
+
+/*
+ * Like sigaction() but includes an udpate_only flag.
+ * In update-only mode, don't override SIG_IGN.
+ */
+int
+sudo_sigaction(int signo, struct sigaction *sa, struct sigaction *osa, bool update_only)
+{
+    /* 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;
+           }
+       }
+    }
+    return sigaction(signo, sa, osa);
+}
index c81e2eb32fe103ed09f6fd09f5f9718d250a6101..1246b26f577575c4dfa13eaf7377a17f7e488795 100644 (file)
@@ -95,7 +95,6 @@ struct plugin_container policy_plugin;
 struct plugin_container_list io_plugins;
 struct user_details user_details;
 const char *list_user, *runas_user, *runas_group; /* extern for parse_args.c */
-int signal_pipe[2];
 static int sudo_mode;
 
 /*
@@ -107,7 +106,6 @@ static void sudo_check_suid(const char *path);
 static char **get_user_info(struct user_details *);
 static void command_info_to_details(char * const info[],
     struct command_details *details);
-static void setup_signals(void);
 
 /* Policy plugin convenience functions. */
 static int policy_open(struct plugin_container *plugin, char * const settings[],
@@ -209,7 +207,7 @@ main(int argc, char *argv[], char *envp[])
            errorx(1, _("unable to initialize policy plugin"));
     }
 
-    setup_signals();
+    init_signals();
 
     switch (sudo_mode & MODE_MASK) {
        case MODE_VERSION:
@@ -1249,43 +1247,3 @@ iolog_unlink(struct plugin_container *plugin)
 
     debug_return;
 }
-
-static void
-sudo_handler(int signo)
-{
-    /*
-     * The pipe is non-blocking, if we overflow the kernel's pipe
-     * buffer we drop the signal.  This is not a problem in practice.
-     */
-    ignore_result(write(signal_pipe[1], &signo, sizeof(signo)));
-}
-
-/*
- * Trap tty-generated signals so we can't be killed before calling
- * the policy close function.  The signal pipe will be checked
- * in sudo_execute().
- */
-static void
-setup_signals(void)
-{
-    struct sigaction sa;
-    debug_decl(setup_signals, SUDO_DEBUG_MAIN)
-
-    /*
-     * We use a pipe to atomically handle signal notification within
-     * the select() loop without races (we may not have pselect()).
-     */
-    if (pipe_nonblock(signal_pipe) != 0)
-       error(1, _("unable to create pipe"));
-
-    /* XXX - should not install handler if ignored by default. */
-    memset(&sa, 0, sizeof(sa));
-    sigfillset(&sa.sa_mask);
-    sa.sa_flags = SA_RESTART;
-    sa.sa_handler = sudo_handler;
-    sigaction(SIGINT, &sa, NULL);
-    sigaction(SIGQUIT, &sa, NULL);
-    sigaction(SIGTSTP, &sa, NULL);
-
-    debug_return;
-}
index 6887a13dd2261d0efc5fcd34d4f78750c2dc2a5a..1517b560f2681925a02e22f6a37b066dc32d473c 100644 (file)
@@ -184,8 +184,6 @@ void zero_bytes(volatile void *, size_t);
 /* exec.c */
 int pipe_nonblock(int fds[2]);
 int sudo_execute(struct command_details *details, struct command_status *cstat);
-void restore_signals(void);
-void save_signals(void);
 
 /* term.c */
 int term_cbreak(int);
@@ -218,7 +216,6 @@ int run_command(struct command_details *details);
 int os_init_common(int argc, char *argv[], char *envp[]);
 extern const char *list_user, *runas_user, *runas_group;
 extern struct user_details user_details;
-extern int signal_pipe[2];
 
 /* sudo_edit.c */
 int sudo_edit(struct command_details *details);
@@ -267,4 +264,12 @@ int sudo_setgroups(int ngids, const GETGROUPS_T *gids);
 /* ttyname.c */
 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);
+void init_signals(void);
+void restore_signals(void);
+void save_signals(void);
+
 #endif /* _SUDO_SUDO_H */