From: Todd C. Miller Date: Sun, 25 Nov 2012 14:34:26 +0000 (-0500) Subject: Add plugin_setjmp() wrapper for siglongjmp(error_jmp, 1) so we don't X-Git-Tag: SUDO_1_8_7~1^2~315 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5496ffe1e8e636dc8b145308cff1746681ab6df8;p=sudo Add plugin_setjmp() wrapper for siglongjmp(error_jmp, 1) so we don't need error_jmp to be extern. Also add plugin_clearjmp() that clears a flag so error()/errorx() knows when to call exit() vs. longjmp(). --- diff --git a/plugins/sudoers/iolog.c b/plugins/sudoers/iolog.c index 40b015257..1317400e3 100644 --- a/plugins/sudoers/iolog.c +++ b/plugins/sudoers/iolog.c @@ -52,8 +52,6 @@ #include "sudoers.h" -extern sigjmp_buf error_jmp; - union io_fd { FILE *f; #ifdef HAVE_ZLIB_H @@ -478,7 +476,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, if (argc == 0) debug_return_bool(true); - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ rval = -1; goto done; @@ -603,6 +601,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, rval = true; done: + plugin_clearjmp(); efree(tofree); if (details.runas_pw) sudo_pw_delref(details.runas_pw); @@ -620,8 +619,9 @@ sudoers_io_close(int exit_status, int error) int i; debug_decl(sudoers_io_close, SUDO_DEBUG_PLUGIN) - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ + plugin_clearjmp(); debug_return; } @@ -643,8 +643,9 @@ sudoers_io_version(int verbose) { debug_decl(sudoers_io_version, SUDO_DEBUG_PLUGIN) - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ + plugin_clearjmp(); debug_return_bool(-1); } @@ -665,8 +666,9 @@ sudoers_io_log(const char *buf, unsigned int len, int idx) gettimeofday(&now, NULL); - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ + plugin_clearjmp(); debug_return_bool(-1); } diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index 3823fdb08..6c62c3a38 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -74,8 +74,6 @@ static int should_mail(int); static void mysyslog(int, const char *, ...); static char *new_logline(const char *, int); -extern sigjmp_buf error_jmp; - extern char **NewArgv; /* XXX - for auditing */ #define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */ @@ -529,7 +527,7 @@ log_fatal(int flags, const char *fmt, ...) /* Exit the plugin. */ sudoers_cleanup(0); sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys); - siglongjmp(error_jmp, 1); + plugin_longjmp(1); } #define MAX_MAILFLAGS 63 diff --git a/plugins/sudoers/plugin_error.c b/plugins/sudoers/plugin_error.c index 80369a6d0..9bab1fbbc 100644 --- a/plugins/sudoers/plugin_error.c +++ b/plugins/sudoers/plugin_error.c @@ -41,7 +41,8 @@ static void _warning(int, const char *, va_list); void sudoers_cleanup(int); -sigjmp_buf error_jmp; +static sigjmp_buf error_jmp; +static bool setjmp_enabled = false; extern sudo_conv_t sudo_conv; @@ -54,7 +55,7 @@ error2(int eval, const char *fmt, ...) _warning(1, fmt, ap); va_end(ap); sudoers_cleanup(0); - if (sudo_conv != NULL) + if (setjmp_enabled) siglongjmp(error_jmp, eval); else exit(eval); @@ -69,7 +70,7 @@ errorx2(int eval, const char *fmt, ...) _warning(0, fmt, ap); va_end(ap); sudoers_cleanup(0); - if (sudo_conv != NULL) + if (setjmp_enabled) siglongjmp(error_jmp, eval); else exit(eval); @@ -80,7 +81,7 @@ verror2(int eval, const char *fmt, va_list ap) { _warning(1, fmt, ap); sudoers_cleanup(0); - if (sudo_conv != NULL) + if (setjmp_enabled) siglongjmp(error_jmp, eval); else exit(eval); @@ -91,7 +92,7 @@ verrorx2(int eval, const char *fmt, va_list ap) { _warning(0, fmt, ap); sudoers_cleanup(0); - if (sudo_conv != NULL) + if (setjmp_enabled) siglongjmp(error_jmp, eval); else exit(eval); @@ -188,3 +189,22 @@ warning_restore_locale(void) { sudoers_setlocale(oldlocale, NULL); } + +int +plugin_setjmp(void) +{ + setjmp_enabled = true; + return sigsetjmp(error_jmp, 1); +} + +void +plugin_longjmp(int val) +{ + siglongjmp(error_jmp, val); +} + +void +plugin_clearjmp(void) +{ + setjmp_enabled = false; +} diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c index 4948ed5bf..eb942301b 100644 --- a/plugins/sudoers/policy.c +++ b/plugins/sudoers/policy.c @@ -73,8 +73,6 @@ static const char *interfaces_string; extern char *login_style; #endif /* HAVE_BSD_AUTH_H */ -extern sigjmp_buf error_jmp; - /* * Deserialize args, settings and user_info arrays. * Fills in struct sudo_user and other common sudoers state. @@ -469,9 +467,10 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation, if (sudo_version < SUDO_API_MKVERSION(1, 2)) args = NULL; - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ rewind_perms(); + plugin_clearjmp(); debug_return_bool(-1); } @@ -487,8 +486,9 @@ sudoers_policy_close(int exit_status, int error_code) { debug_decl(sudoers_policy_close, SUDO_DEBUG_PLUGIN) - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ + plugin_clearjmp(); debug_return; } @@ -536,8 +536,9 @@ sudoers_policy_init_session(struct passwd *pwd, char **user_env[]) if (sudo_version < SUDO_API_MKVERSION(1, 2)) user_env = NULL; - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ + plugin_clearjmp(); debug_return_bool(-1); } @@ -578,10 +579,11 @@ sudoers_policy_invalidate(int remove) debug_decl(sudoers_policy_invalidate, SUDO_DEBUG_PLUGIN) user_cmnd = "kill"; - if (sigsetjmp(error_jmp, 1) == 0) { + if (plugin_setjmp() == 0) { remove_timestamp(remove); sudoers_cleanup(0); } + plugin_clearjmp(); debug_return; } @@ -621,8 +623,9 @@ sudoers_policy_version(int verbose) { debug_decl(sudoers_policy_version, SUDO_DEBUG_PLUGIN) - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* error recovery via error(), errorx() or log_fatal() */ + plugin_clearjmp(); debug_return_bool(-1); } diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 05f5fa4ab..941256410 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -231,7 +231,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], (void) sigaction(SIGTSTP, &sa, &saved_sa_tstp); /* XXX - would like to move this to policy.c but need the cleanup. */ - if (sigsetjmp(error_jmp, 1)) { + if (plugin_setjmp() != 0) { /* error recovery via error(), errorx() or log_fatal() */ rval = -1; goto done; @@ -522,6 +522,7 @@ bad: rval = false; done: + plugin_clearjmp(); rewind_perms(); /* Restore signal handlers before we exec. */ diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 8f2300210..1b5eafb79 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -23,7 +23,6 @@ #define _SUDO_SUDOERS_H #include -#include #ifdef HAVE_STDBOOL_H # include #else @@ -371,7 +370,9 @@ int group_plugin_query(const char *user, const char *group, int sudo_setgroups(int ngids, const GETGROUPS_T *gids); /* plugin_error.c */ -extern sigjmp_buf error_jmp; +int plugin_setjmp(void); +void plugin_clearjmp(void); +void plugin_longjmp(int val) __attribute__((__noreturn__)); #ifndef _SUDO_MAIN extern struct sudo_user sudo_user;