From 3e4c7eed3178bbf6c8c326ba3ecfd762ff2019cd Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 17 Aug 2016 14:38:00 -0600 Subject: [PATCH] Move the ignoring of I/O log plugin errors into the I/O log plugin itself. --- plugins/sudoers/iolog.c | 58 +++++++++++++++++++++++++++-------------- src/exec_pty.c | 18 ------------- src/sudo.c | 3 --- src/sudo.h | 1 - 4 files changed, 39 insertions(+), 41 deletions(-) diff --git a/plugins/sudoers/iolog.c b/plugins/sudoers/iolog.c index d4db4ce3c..36b233001 100644 --- a/plugins/sudoers/iolog.c +++ b/plugins/sudoers/iolog.c @@ -63,9 +63,12 @@ struct iolog_details { struct group *runas_gr; int lines; int cols; + bool ignore_iolog_errors; }; +static struct iolog_details iolog_details; static bool iolog_compress = false; +static bool warned = false; static struct timeval last_time; static unsigned int sessid_max = SESSID_MAX; @@ -301,6 +304,7 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7]) if (lseek(fd, 0, SEEK_SET) == -1 || write(fd, buf, 7) != 7) { #endif log_warning(SLOG_SEND_MAIL, N_("unable to write to %s"), pathbuf); + warned = true; goto done; } rval = true; @@ -448,6 +452,11 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[], } break; case 'i': + if (strncmp(*cur, "ignore_iolog_errors=", sizeof("ignore_iolog_errors=") - 1) == 0) { + if (sudo_strtobool(*cur + sizeof("ignore_iolog_errors=") - 1) == true) + details->ignore_iolog_errors = true; + continue; + } if (strncmp(*cur, "iolog_path=", sizeof("iolog_path=") - 1) == 0) { details->iolog_path = *cur + sizeof("iolog_path=") - 1; continue; @@ -599,7 +608,6 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, int argc, char * const argv[], char * const user_env[], char * const args[]) { struct sudo_conf_debug_file_list debug_files = TAILQ_HEAD_INITIALIZER(debug_files); - struct iolog_details details; char pathbuf[PATH_MAX], sessid[7]; char *tofree = NULL; char * const *cur; @@ -615,8 +623,6 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, if (argc == 0) debug_return_int(true); - memset(&details, 0, sizeof(details)); - bindtextdomain("sudoers", LOCALEDIR); /* Initialize the debug subsystem. */ @@ -637,13 +643,13 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, /* * Pull iolog settings out of command_info. */ - if (!iolog_deserialize_info(&details, user_info, command_info)) { + if (!iolog_deserialize_info(&iolog_details, user_info, command_info)) { rval = false; goto done; } /* If no I/O log path defined we need to figure it out ourselves. */ - if (details.iolog_path == NULL) { + if (iolog_details.iolog_path == NULL) { /* Get next session ID and convert it into a path. */ tofree = malloc(sizeof(_PATH_SUDO_IO_LOGDIR) + sizeof(sessid) + 2); if (tofree == NULL) { @@ -658,21 +664,21 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, snprintf(tofree + sizeof(_PATH_SUDO_IO_LOGDIR), sizeof(sessid) + 2, "%c%c/%c%c/%c%c", sessid[0], sessid[1], sessid[2], sessid[3], sessid[4], sessid[5]); - details.iolog_path = tofree; + iolog_details.iolog_path = tofree; } /* * Make local copy of I/O log path and create it, along with any * intermediate subdirs. Calls mkdtemp() if iolog_path ends in XXXXXX. */ - len = mkdir_iopath(details.iolog_path, pathbuf, sizeof(pathbuf)); + len = mkdir_iopath(iolog_details.iolog_path, pathbuf, sizeof(pathbuf)); if (len >= sizeof(pathbuf)) goto done; /* Write log file with user and command details. */ if (gettimeofday(&last_time, NULL) == -1) goto done; - write_info_log(pathbuf, len, &details, argv, &last_time); + write_info_log(pathbuf, len, &iolog_details, argv, &last_time); /* Create the timing and I/O log files. */ for (i = 0; i < IOFD_MAX; i++) { @@ -698,13 +704,17 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, done: free(tofree); - if (details.runas_pw) - sudo_pw_delref(details.runas_pw); - if (details.runas_gr) - sudo_gr_delref(details.runas_gr); + if (iolog_details.runas_pw) + sudo_pw_delref(iolog_details.runas_pw); + if (iolog_details.runas_gr) + sudo_gr_delref(iolog_details.runas_gr); sudo_freepwcache(); sudo_freegrcache(); + /* Ignore errors if they occur if the policy says so. */ + if (rval == -1 && iolog_details.ignore_iolog_errors) + rval = 0; + debug_return_int(rval); } @@ -730,8 +740,12 @@ sudoers_io_close(int exit_status, int error) errstr = strerror(errno); } - if (errstr != NULL) - sudo_warnx(U_("unable to write to I/O log file: %s"), errstr); + if (errstr != NULL && !warned) { + /* Only warn about I/O log file errors once. */ + log_warning(SLOG_SEND_MAIL, + N_("unable to write to I/O log file: %s"), errstr); + warned = true; + } sudoers_debug_deregister(); @@ -756,7 +770,6 @@ static int sudoers_io_log(const char *buf, unsigned int len, int idx) { struct timeval now, delay; - static bool warned = false; const char *errstr = NULL; int rval = true; debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN) @@ -807,10 +820,17 @@ sudoers_io_log(const char *buf, unsigned int len, int idx) last_time.tv_sec = now.tv_sec; last_time.tv_usec = now.tv_usec; - if (errstr != NULL && !warned) { - /* Only warn about I/O log file errors once. */ - sudo_warnx(U_("unable to write to I/O log file: %s"), errstr); - warned = true; + if (rval == -1) { + if (errstr != NULL && !warned) { + /* Only warn about I/O log file errors once. */ + log_warning(SLOG_SEND_MAIL, + N_("unable to write to I/O log file: %s"), errstr); + warned = true; + } + + /* Ignore errors if they occur if the policy says so. */ + if (iolog_details.ignore_iolog_errors) + rval = true; } debug_return_int(rval); diff --git a/src/exec_pty.c b/src/exec_pty.c index 803592038..a22bee6cf 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -89,7 +89,6 @@ static int ttymode = TERM_COOKED; static pid_t ppgrp, cmnd_pgrp, mon_pgrp; static sigset_t ttyblock; static struct io_buffer_list iobufs; -static bool ignore_iolog_errors; static void del_io_events(bool nonblocking); static int exec_monitor(struct command_details *details, int backchannel); @@ -219,8 +218,6 @@ log_ttyin(const char *buf, unsigned int n, struct io_buffer *iob) /* Error: disable plugin's I/O function. */ plugin->u.io->log_ttyin = NULL; } - if (!ignore_iolog_errors) - rval = false; break; } } @@ -252,8 +249,6 @@ log_stdin(const char *buf, unsigned int n, struct io_buffer *iob) /* Error: disable plugin's I/O function. */ plugin->u.io->log_stdin = NULL; } - if (!ignore_iolog_errors) - rval = false; break; } } @@ -285,8 +280,6 @@ log_ttyout(const char *buf, unsigned int n, struct io_buffer *iob) /* Error: disable plugin's I/O function. */ plugin->u.io->log_ttyout = NULL; } - if (!ignore_iolog_errors) - rval = false; break; } } @@ -330,8 +323,6 @@ log_stdout(const char *buf, unsigned int n, struct io_buffer *iob) /* Error: disable plugin's I/O function. */ plugin->u.io->log_stdout = NULL; } - if (!ignore_iolog_errors) - rval = false; break; } } @@ -375,8 +366,6 @@ log_stderr(const char *buf, unsigned int n, struct io_buffer *iob) /* Error: disable plugin's I/O function. */ plugin->u.io->log_stderr = NULL; } - if (!ignore_iolog_errors) - rval = false; break; } } @@ -749,13 +738,6 @@ fork_pty(struct command_details *details, int sv[], sigset_t *omask) sigaddset(&ttyblock, SIGTTIN); sigaddset(&ttyblock, SIGTTOU); - /* - * The security policy may tell us to ignore errors from the - * I/O log functions. - */ - if (!ISSET(details->flags, CD_IGNORE_IOLOG_ERRS)) - ignore_iolog_errors = true; - /* * Setup stdin/stdout/stderr for child, to be duped after forking. * In background mode there is no stdin. diff --git a/src/sudo.c b/src/sudo.c index b711c0bd3..58085e9e7 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -675,9 +675,6 @@ command_info_to_details(char * const info[], struct command_details *details) break; } break; - case 'i': - SET_FLAG("ignore_iolog_errors=", CD_IGNORE_IOLOG_ERRS) - break; case 'l': SET_STRING("login_class=", login_class) break; diff --git a/src/sudo.h b/src/sudo.h index 490f1d437..e871acde4 100644 --- a/src/sudo.h +++ b/src/sudo.h @@ -130,7 +130,6 @@ struct user_details { #define CD_SUDOEDIT_FOLLOW 0x10000 #define CD_SUDOEDIT_CHECKDIR 0x20000 #define CD_SET_GROUPS 0x40000 -#define CD_IGNORE_IOLOG_ERRS 0x80000 struct preserved_fd { TAILQ_ENTRY(preserved_fd) entries; -- 2.40.0