unix: reset signal mask before execve()
Like the previous commit, except now the signal mask is reset instead of the signal disposition. This does open a race window where blocked signals can get delivered in the interval between the pthread_sigmask() call and the execve() call (and may end up terminating the process) but that cannot be helped; the same caveat applies to the previous commit. Fixes: https://github.com/nodejs/node/issues/13662 PR-URL: https://github.com/libuv/libuv/pull/1376 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
28eb1d44f5
commit
11563e179f
@ -279,8 +279,10 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
int stdio_count,
|
||||
int (*pipes)[2],
|
||||
int error_fd) {
|
||||
sigset_t set;
|
||||
int close_fd;
|
||||
int use_fd;
|
||||
int err;
|
||||
int fd;
|
||||
int n;
|
||||
|
||||
@ -393,6 +395,15 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
/* Reset signal mask. */
|
||||
sigemptyset(&set);
|
||||
err = pthread_sigmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
if (err != 0) {
|
||||
uv__write_int(error_fd, -err);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
execvp(options->file, options->args);
|
||||
uv__write_int(error_fd, -errno);
|
||||
_exit(127);
|
||||
|
||||
@ -931,6 +931,12 @@ TEST_IMPL(kill) {
|
||||
|
||||
/* Verify that uv_spawn() resets the signal disposition. */
|
||||
#ifndef _WIN32
|
||||
{
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGTERM);
|
||||
ASSERT(0 == pthread_sigmask(SIG_BLOCK, &set, NULL));
|
||||
}
|
||||
ASSERT(SIG_ERR != signal(SIGTERM, SIG_IGN));
|
||||
#endif
|
||||
|
||||
@ -938,6 +944,12 @@ TEST_IMPL(kill) {
|
||||
ASSERT(r == 0);
|
||||
|
||||
#ifndef _WIN32
|
||||
{
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGTERM);
|
||||
ASSERT(0 == pthread_sigmask(SIG_UNBLOCK, &set, NULL));
|
||||
}
|
||||
ASSERT(SIG_ERR != signal(SIGTERM, SIG_DFL));
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user