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
This commit is contained in:
41
src/sudo.c
41
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user