Ignore SIGPIPE for the duration of sudo and not just in a few select
places. We have no control over what nss, PAM modules or sudo plugins might do so ignoring SIGPIPE is safest.
This commit is contained in:
@@ -1111,6 +1111,7 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
++oo SIGALRM
|
||||
++oo SIGHUP
|
||||
++oo SIGINT
|
||||
++oo SIGPIPE
|
||||
++oo SIGQUIT
|
||||
++oo SIGTERM
|
||||
++oo SIGTSTP
|
||||
@@ -1121,7 +1122,8 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
call the plugin's cclloossee() function with an exit status of 128 plus the
|
||||
value of the signal that was received. This allows for consistent
|
||||
logging of commands killed by a signal for plugins that log such
|
||||
information in their cclloossee() function.
|
||||
information in their cclloossee() function. An exception to this is SIGPIPE,
|
||||
which is ignored until the command is executed.
|
||||
|
||||
A plugin may temporarily install its own signal handlers but must restore
|
||||
the original handler before the plugin function returns.
|
||||
|
@@ -1978,6 +1978,9 @@ executed:
|
||||
\fRSIGINT\fR
|
||||
.TP 4n
|
||||
\fB\(bu\fR
|
||||
\fRSIGPIPE\fR
|
||||
.TP 4n
|
||||
\fB\(bu\fR
|
||||
\fRSIGQUIT\fR
|
||||
.TP 4n
|
||||
\fB\(bu\fR
|
||||
@@ -2003,6 +2006,9 @@ This allows for consistent logging of commands killed by a signal
|
||||
for plugins that log such information in their
|
||||
\fBclose\fR()
|
||||
function.
|
||||
An exception to this is
|
||||
\fRSIGPIPE\fR,
|
||||
which is ignored until the command is executed.
|
||||
.PP
|
||||
A plugin may temporarily install its own signal handlers but must
|
||||
restore the original handler before the plugin function returns.
|
||||
|
@@ -1735,6 +1735,8 @@ executed:
|
||||
.It
|
||||
.Dv SIGINT
|
||||
.It
|
||||
.Dv SIGPIPE
|
||||
.It
|
||||
.Dv SIGQUIT
|
||||
.It
|
||||
.Dv SIGTERM
|
||||
@@ -1756,6 +1758,9 @@ This allows for consistent logging of commands killed by a signal
|
||||
for plugins that log such information in their
|
||||
.Fn close
|
||||
function.
|
||||
An exception to this is
|
||||
.Ev SIGPIPE ,
|
||||
which is ignored until the command is executed.
|
||||
.Pp
|
||||
A plugin may temporarily install its own signal handlers but must
|
||||
restore the original handler before the plugin function returns.
|
||||
|
@@ -2975,17 +2975,10 @@ sudo_ldap_open(struct sudo_nss *nss)
|
||||
{
|
||||
LDAP *ld;
|
||||
int rc = -1;
|
||||
sigaction_t sa, saved_sa_pipe;
|
||||
bool ldapnoinit = false;
|
||||
struct sudo_ldap_handle *handle;
|
||||
debug_decl(sudo_ldap_open, SUDOERS_DEBUG_LDAP)
|
||||
|
||||
/* Ignore SIGPIPE if we cannot bind to the server. */
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
|
||||
|
||||
if (!sudo_ldap_read_config())
|
||||
goto done;
|
||||
|
||||
@@ -3071,7 +3064,6 @@ sudo_ldap_open(struct sudo_nss *nss)
|
||||
nss->handle = handle;
|
||||
|
||||
done:
|
||||
(void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
|
||||
debug_return_int(rc == LDAP_SUCCESS ? 0 : -1);
|
||||
}
|
||||
|
||||
|
@@ -542,7 +542,6 @@ send_mail(const char *fmt, ...)
|
||||
const char *timestr;
|
||||
int fd, pfd[2], status;
|
||||
pid_t pid, rv;
|
||||
sigaction_t sa;
|
||||
struct stat sb;
|
||||
va_list ap;
|
||||
#ifndef NO_ROOT_MAILER
|
||||
@@ -619,13 +618,6 @@ send_mail(const char *fmt, ...)
|
||||
sudo_endgrent();
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
/* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_INTERRUPT;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void) sigaction(SIGPIPE, &sa, NULL);
|
||||
|
||||
if (pipe(pfd) == -1) {
|
||||
mysyslog(LOG_ERR, _("unable to open pipe: %m"));
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to open pipe: %s",
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include "sudo.h"
|
||||
#include "sudo_exec.h"
|
||||
|
||||
int signal_pipe[2];
|
||||
|
||||
@@ -151,6 +152,13 @@ init_signals(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Ignore SIGPIPE until exec. */
|
||||
if (saved_signals[SAVED_SIGPIPE].sa.sa_handler != SIG_IGN) {
|
||||
sa.sa_handler = SIG_IGN;
|
||||
if (sigaction(SIGPIPE, &sa, NULL) != 0)
|
||||
sudo_warn(U_("unable to set handler for signal %d"), SIGPIPE);
|
||||
}
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
|
@@ -188,10 +188,13 @@ main(int argc, char *argv[], char *envp[])
|
||||
/* Make sure we are setuid root. */
|
||||
sudo_check_suid(argc > 0 ? argv[0] : "sudo");
|
||||
|
||||
/* Reset signal mask and save signal state. */
|
||||
/* Save original signal state and setup default signal handlers. */
|
||||
save_signals();
|
||||
init_signals();
|
||||
|
||||
/* Reset signal mask to the default value (unblock). */
|
||||
(void) sigemptyset(&mask);
|
||||
(void) sigprocmask(SIG_SETMASK, &mask, NULL);
|
||||
save_signals();
|
||||
|
||||
/* Parse the rest of sudo.conf. */
|
||||
sudo_conf_read(NULL, SUDO_CONF_ALL & ~SUDO_CONF_DEBUG);
|
||||
@@ -230,8 +233,6 @@ main(int argc, char *argv[], char *envp[])
|
||||
sudo_fatalx(U_("unable to initialize policy plugin"));
|
||||
}
|
||||
|
||||
init_signals();
|
||||
|
||||
switch (sudo_mode & MODE_MASK) {
|
||||
case MODE_VERSION:
|
||||
policy_show_version(&policy_plugin, !user_details.uid);
|
||||
|
@@ -85,7 +85,7 @@ tgetpass(const char *prompt, int timeout, int flags,
|
||||
struct sudo_conv_callback *callback)
|
||||
{
|
||||
sigaction_t sa, savealrm, saveint, savehup, savequit, saveterm;
|
||||
sigaction_t savetstp, savettin, savettou, savepipe;
|
||||
sigaction_t savetstp, savettin, savettou;
|
||||
char *pass;
|
||||
static const char *askpass;
|
||||
static char buf[SUDO_CONV_REPL_MAX + 1];
|
||||
@@ -168,10 +168,6 @@ restart:
|
||||
(void) sigaction(SIGTTIN, &sa, &savettin);
|
||||
(void) sigaction(SIGTTOU, &sa, &savettou);
|
||||
|
||||
/* Ignore SIGPIPE in case stdin is a pipe and TGP_STDIN is set */
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void) sigaction(SIGPIPE, &sa, &savepipe);
|
||||
|
||||
if (prompt) {
|
||||
if (write(output, prompt, strlen(prompt)) == -1)
|
||||
goto restore;
|
||||
@@ -198,7 +194,6 @@ restore:
|
||||
(void) sigaction(SIGTSTP, &savetstp, NULL);
|
||||
(void) sigaction(SIGTTIN, &savettin, NULL);
|
||||
(void) sigaction(SIGTTOU, &savettou, NULL);
|
||||
(void) sigaction(SIGPIPE, &savepipe, NULL);
|
||||
|
||||
/* Restore old tty settings. */
|
||||
if (!ISSET(flags, TGP_ECHO)) {
|
||||
@@ -252,7 +247,6 @@ static char *
|
||||
sudo_askpass(const char *askpass, const char *prompt)
|
||||
{
|
||||
static char buf[SUDO_CONV_REPL_MAX + 1], *pass;
|
||||
sigaction_t sa, saved_sa_pipe;
|
||||
int pfd[2], status;
|
||||
pid_t child;
|
||||
debug_decl(sudo_askpass, SUDO_DEBUG_CONV)
|
||||
@@ -286,18 +280,10 @@ sudo_askpass(const char *askpass, const char *prompt)
|
||||
_exit(255);
|
||||
}
|
||||
|
||||
/* Ignore SIGPIPE in case child exits prematurely */
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_INTERRUPT;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
|
||||
|
||||
/* Get response from child (askpass) and restore SIGPIPE handler */
|
||||
/* Get response from child (askpass). */
|
||||
(void) close(pfd[1]);
|
||||
pass = getln(pfd[0], buf, sizeof(buf), 0);
|
||||
(void) close(pfd[0]);
|
||||
(void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
|
||||
|
||||
/* Wait for child to exit. */
|
||||
for (;;) {
|
||||
|
Reference in New Issue
Block a user