From 89b32378c84f6d877507dc9c01ab4e144bdf4d15 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 20 May 2019 02:03:48 +0200 Subject: [PATCH] src: forbid reset_handler for SIGSEGV handling This is not easily implementable, and should be explicitly disallowed. PR-URL: https://github.com/nodejs/node/pull/27775 Refs: https://github.com/nodejs/node/pull/27246 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Rich Trott --- src/node.cc | 14 ++++++++------ src/node.h | 8 ++++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/node.cc b/src/node.cc index f4a953a7c38abf..99e6f74b472fdc 100644 --- a/src/node.cc +++ b/src/node.cc @@ -477,13 +477,15 @@ void LoadEnvironment(Environment* env) { USE(StartMainThreadExecution(env)); } +#ifdef __POSIX__ +typedef void (*sigaction_cb)(int signo, siginfo_t* info, void* ucontext); +#endif #if NODE_USE_V8_WASM_TRAP_HANDLER -static std::atomic - previous_sigsegv_action; +static std::atomic previous_sigsegv_action; void TrapWebAssemblyOrContinue(int signo, siginfo_t* info, void* ucontext) { if (!v8::TryHandleWebAssemblyTrapPosix(signo, info, ucontext)) { - auto prev = previous_sigsegv_action.load(); + sigaction_cb prev = previous_sigsegv_action.load(); if (prev != nullptr) { prev(signo, info, ucontext); } else { @@ -502,13 +504,13 @@ void TrapWebAssemblyOrContinue(int signo, siginfo_t* info, void* ucontext) { #ifdef __POSIX__ void RegisterSignalHandler(int signal, - void (*handler)(int signal, - siginfo_t* info, - void* ucontext), + sigaction_cb handler, bool reset_handler) { + CHECK_NOT_NULL(handler); #if NODE_USE_V8_WASM_TRAP_HANDLER if (signal == SIGSEGV) { CHECK(previous_sigsegv_action.is_lock_free()); + CHECK(!reset_handler); previous_sigsegv_action.store(handler); return; } diff --git a/src/node.h b/src/node.h index 65997fbc7b9e87..049690d92fb9e4 100644 --- a/src/node.h +++ b/src/node.h @@ -815,8 +815,12 @@ class NODE_EXTERN AsyncResource { }; #ifndef _WIN32 -// Register a signal handler without interrupting -// any handlers that node itself needs. +// Register a signal handler without interrupting any handlers that node +// itself needs. This does override handlers registered through +// process.on('SIG...', function() { ... }). The `reset_handler` flag indicates +// whether the signal handler for the given signal should be reset to its +// default value before executing the handler (i.e. it works like SA_RESETHAND). +// The `reset_handler` flag is invalid when `signal` is SIGSEGV. NODE_EXTERN void RegisterSignalHandler(int signal, void (*handler)(int signal,