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:
Ben Noordhuis 2017-06-14 12:32:40 +02:00
parent 28eb1d44f5
commit 11563e179f
2 changed files with 23 additions and 0 deletions

View File

@ -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);

View File

@ -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