From: Todd C. Miller Date: Sat, 26 Sep 2015 16:53:16 +0000 (-0600) Subject: When the command sudo is running is killed by a signal, sudo will X-Git-Tag: SUDO_1_8_15^2~36 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9486afb4e5e115be4fac518fa28445259b3ecf6c;p=sudo When the command sudo is running is killed by a signal, sudo will now send itself the same signal with the default signal handler instead of exiting. The bash shell appears to ignore some signals, e.g. SIGINT, unless the command is killed by that signal. This makes the behavior of commands run under sudo the same as without sudo when bash is the shell. Bug #722 --- diff --git a/src/sudo.c b/src/sudo.c index 64fd65787..c8ae36517 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -134,7 +134,7 @@ __dso_public int main(int argc, char *argv[], char *envp[]); int main(int argc, char *argv[], char *envp[]) { - int nargc, ok, exitcode = 0; + int nargc, ok, status = 0; char **nargv, **env_add; char **user_info, **command_info, **argv_out, **user_env_out; struct sudo_settings *settings; @@ -283,17 +283,29 @@ main(int argc, char *argv[], char *envp[]) (void) setrlimit(RLIMIT_CORE, &corelimit); #endif /* RLIMIT_CORE */ if (ISSET(command_details.flags, CD_SUDOEDIT)) { - exitcode = sudo_edit(&command_details); + status = sudo_edit(&command_details); } else { - exitcode = run_command(&command_details); + status = run_command(&command_details); } /* The close method was called by sudo_edit/run_command. */ break; default: sudo_fatalx(U_("unexpected sudo mode 0x%x"), sudo_mode); } - sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode); - exit(exitcode); + if (WIFSIGNALED(status)) { + sigaction_t sa; + + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_DFL; + sigaction(SIGINT, &sa, NULL); + sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, + WTERMSIG(status) | 128); + kill(getpid(), WTERMSIG(status)); + } + sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, + WEXITSTATUS(status)); + exit(WEXITSTATUS(status)); } int @@ -1068,7 +1080,7 @@ run_command(struct command_details *details) { struct plugin_container *plugin; struct command_status cstat; - int exitcode = 1; + int status = 1; debug_decl(run_command, SUDO_DEBUG_EXEC) cstat.type = CMD_INVALID; @@ -1087,32 +1099,29 @@ run_command(struct command_details *details) "calling I/O close with errno %d", cstat.val); iolog_close(plugin, 0, cstat.val); } - exitcode = 1; + status = 1; break; case CMD_WSTATUS: /* Command ran, exited or was killed. */ - if (WIFEXITED(cstat.val)) - exitcode = WEXITSTATUS(cstat.val); - else if (WIFSIGNALED(cstat.val)) - exitcode = WTERMSIG(cstat.val) | 128; + status = cstat.val; #ifdef HAVE_SELINUX if (ISSET(details->flags, CD_SUDOEDIT_COPY)) break; #endif sudo_debug_printf(SUDO_DEBUG_DEBUG, - "calling policy close with wait status %d", cstat.val); - policy_close(&policy_plugin, cstat.val, 0); + "calling policy close with wait status %d", status); + policy_close(&policy_plugin, status, 0); TAILQ_FOREACH(plugin, &io_plugins, entries) { sudo_debug_printf(SUDO_DEBUG_DEBUG, - "calling I/O close with wait status %d", cstat.val); - iolog_close(plugin, cstat.val, 0); + "calling I/O close with wait status %d", status); + iolog_close(plugin, status, 0); } break; default: sudo_warnx(U_("unexpected child termination condition: %d"), cstat.type); break; } - debug_return_int(exitcode); + debug_return_int(status); } /*