From b7ae7977a6d921b83d09cf824a5b301ecf186a63 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 29 Nov 2012 06:37:13 -0500 Subject: [PATCH] Cannot wrap sigsetjmp() or we end up returning to the wrong place. Use a macro instead. --- common/error.c | 17 +++++------------ include/error.h | 7 +++++++ plugins/sudoers/iolog.c | 16 ++++++++-------- plugins/sudoers/logging.c | 2 +- plugins/sudoers/policy.c | 20 ++++++++++---------- plugins/sudoers/sudoers.c | 4 ++-- plugins/sudoers/sudoers.h | 5 ----- 7 files changed, 33 insertions(+), 38 deletions(-) diff --git a/common/error.c b/common/error.c index fd6cd85b5..6c5f878f4 100644 --- a/common/error.c +++ b/common/error.c @@ -37,7 +37,7 @@ #define DEFAULT_TEXT_DOMAIN "sudo" #include "gettext.h" -static sigjmp_buf error_jmp; +sigjmp_buf error_jmp; static bool setjmp_enabled = false; static struct sudo_error_callback { void (*func)(void); @@ -180,21 +180,14 @@ error_callback_register(void (*func)(void)) return 0; } -int -plugin_setjmp(void) -{ - setjmp_enabled = true; - return sigsetjmp(error_jmp, 1); -} - void -plugin_longjmp(int val) +error_disable_setjmp(void) { - siglongjmp(error_jmp, val); + setjmp_enabled = false; } void -plugin_clearjmp(void) +error_enable_setjmp(void) { - setjmp_enabled = false; + setjmp_enabled = true; } diff --git a/include/error.h b/include/error.h index 8d80cf7fd..88360f84c 100644 --- a/include/error.h +++ b/include/error.h @@ -18,6 +18,7 @@ #define _SUDO_ERROR_H_ #include +#include /* * We wrap error/errorx and warn/warnx so that the same output can @@ -170,9 +171,15 @@ warning_restore_locale(); \ } while (0) +#define error_setjmp() (error_enable_setjmp(), sigsetjmp(error_jmp, 1)) +#define error_longjmp(val) siglongjmp(error_jmp, val) + extern int (*sudo_printf)(int msg_type, const char *fmt, ...); +extern sigjmp_buf error_jmp; int error_callback_register(void (*func)(void)); +void error_disable_setjmp(void); +void error_enable_setjmp(void); void error2(int, const char *, ...) __printflike(2, 3) __attribute__((__noreturn__)); void errorx2(int, const char *, ...) __printflike(2, 3) __attribute__((__noreturn__)); void verror2(int, const char *, va_list ap) __attribute__((__noreturn__)); diff --git a/plugins/sudoers/iolog.c b/plugins/sudoers/iolog.c index 60fba6132..88750312a 100644 --- a/plugins/sudoers/iolog.c +++ b/plugins/sudoers/iolog.c @@ -472,7 +472,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, if (argc == 0) debug_return_bool(true); - if (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ rval = -1; goto done; @@ -597,7 +597,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, rval = true; done: - plugin_clearjmp(); + error_disable_setjmp(); efree(tofree); if (details.runas_pw) sudo_pw_delref(details.runas_pw); @@ -615,9 +615,9 @@ sudoers_io_close(int exit_status, int error) int i; debug_decl(sudoers_io_close, SUDO_DEBUG_PLUGIN) - if (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ - plugin_clearjmp(); + error_disable_setjmp(); debug_return; } @@ -639,9 +639,9 @@ sudoers_io_version(int verbose) { debug_decl(sudoers_io_version, SUDO_DEBUG_PLUGIN) - if (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ - plugin_clearjmp(); + error_disable_setjmp(); debug_return_bool(-1); } @@ -662,9 +662,9 @@ sudoers_io_log(const char *buf, unsigned int len, int idx) gettimeofday(&now, NULL); - if (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ - plugin_clearjmp(); + error_disable_setjmp(); debug_return_bool(-1); } diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index 3aed994b0..f17938553 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -527,7 +527,7 @@ log_fatal(int flags, const char *fmt, ...) /* Exit the plugin. */ sudoers_cleanup(); sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys); - plugin_longjmp(1); + error_longjmp(1); } #define MAX_MAILFLAGS 63 diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c index c65cab9f3..e0cff9f2d 100644 --- a/plugins/sudoers/policy.c +++ b/plugins/sudoers/policy.c @@ -465,10 +465,10 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation, if (sudo_version < SUDO_API_MKVERSION(1, 2)) args = NULL; - if (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ rewind_perms(); - plugin_clearjmp(); + error_disable_setjmp(); debug_return_bool(-1); } @@ -484,9 +484,9 @@ sudoers_policy_close(int exit_status, int error_code) { debug_decl(sudoers_policy_close, SUDO_DEBUG_PLUGIN) - if (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ - plugin_clearjmp(); + error_disable_setjmp(); debug_return; } @@ -534,9 +534,9 @@ sudoers_policy_init_session(struct passwd *pwd, char **user_env[]) if (sudo_version < SUDO_API_MKVERSION(1, 2)) user_env = NULL; - if (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* called via error(), errorx() or log_fatal() */ - plugin_clearjmp(); + error_disable_setjmp(); debug_return_bool(-1); } @@ -577,11 +577,11 @@ sudoers_policy_invalidate(int remove) debug_decl(sudoers_policy_invalidate, SUDO_DEBUG_PLUGIN) user_cmnd = "kill"; - if (plugin_setjmp() == 0) { + if (error_setjmp() == 0) { remove_timestamp(remove); sudoers_cleanup(); } - plugin_clearjmp(); + error_disable_setjmp(); debug_return; } @@ -621,9 +621,9 @@ sudoers_policy_version(int verbose) { debug_decl(sudoers_policy_version, SUDO_DEBUG_PLUGIN) - if (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* error recovery via error(), errorx() or log_fatal() */ - plugin_clearjmp(); + error_disable_setjmp(); debug_return_bool(-1); } diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index a35df036d..f10d4193a 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -233,7 +233,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 (plugin_setjmp() != 0) { + if (error_setjmp() != 0) { /* error recovery via error(), errorx() or log_fatal() */ rval = -1; goto done; @@ -524,7 +524,7 @@ bad: rval = false; done: - plugin_clearjmp(); + error_disable_setjmp(); rewind_perms(); /* Restore signal handlers before we exec. */ diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 3acf6daec..4a3f6e0b2 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -369,11 +369,6 @@ int group_plugin_query(const char *user, const char *group, /* setgroups.c */ int sudo_setgroups(int ngids, const GETGROUPS_T *gids); -/* plugin_error.c */ -int plugin_setjmp(void); -void plugin_clearjmp(void); -void plugin_longjmp(int val) __attribute__((__noreturn__)); - #ifndef _SUDO_MAIN extern struct sudo_user sudo_user; extern struct passwd *list_pw; -- 2.40.0