]> granicus.if.org Git - sudo/commitdiff
Add plugin_setjmp() wrapper for siglongjmp(error_jmp, 1) so we don't
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 25 Nov 2012 14:34:26 +0000 (09:34 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 25 Nov 2012 14:34:26 +0000 (09:34 -0500)
need error_jmp to be extern.  Also add plugin_clearjmp() that clears
a flag so error()/errorx() knows when to call exit() vs. longjmp().

plugins/sudoers/iolog.c
plugins/sudoers/logging.c
plugins/sudoers/plugin_error.c
plugins/sudoers/policy.c
plugins/sudoers/sudoers.c
plugins/sudoers/sudoers.h

index 40b0152571f2202488cc648c2339cfc083d636ee..1317400e38e885512d0d74437a4a3f79140732d0 100644 (file)
@@ -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);
     }
 
index 3823fdb0830e68b6b5ad7c8a44cb350fd4a22edd..6c62c3a38c662a43478b6926b163c7cb34aa6b83 100644 (file)
@@ -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
index 80369a6d02af50cead68b9c17e1142f4e19baade..9bab1fbbc34edea5c8696e6bf60e7d299358314c 100644 (file)
@@ -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;
+}
index 4948ed5bf9cb96829cce56a7155d720155eece26..eb942301b8ef4c5f682775fe2ed22d2561e55764 100644 (file)
@@ -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);
     }
 
index 05f5fa4ababc7a56a88049d9f667b23d8fd0c711..941256410871b87d049d9fcdfd5ad51f89f961fd 100644 (file)
@@ -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. */
index 8f230021030bbc9ec3815a6c85c45739e0e5145d..1b5eafb79bef19c5ee246a47ddc44e56cfd914b4 100644 (file)
@@ -23,7 +23,6 @@
 #define _SUDO_SUDOERS_H
 
 #include <limits.h>
-#include <setjmp.h>
 #ifdef HAVE_STDBOOL_H
 # include <stdbool.h>
 #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;