mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
src: handle wasm out of bound in osx will raise SIGBUS correctly
fix: #46559 OSX will raise both SIGBUS and SIGSEGV when out of bound memory visit, This commit set sigaction in OSX for two signals to handle this. PR-URL: https://github.com/nodejs/node/pull/46561 Fixes: https://github.com/nodejs/node/issues/46559 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: Michael Dawson <midawson@redhat.com>
This commit is contained in:
parent
bd7a8087a5
commit
ed92b1fdaf
24
src/node.cc
24
src/node.cc
@ -362,10 +362,19 @@ static LONG TrapWebAssemblyOrContinue(EXCEPTION_POINTERS* exception) {
|
||||
}
|
||||
#else
|
||||
static std::atomic<sigaction_cb> previous_sigsegv_action;
|
||||
// TODO(align behavior between macos and other in next major version)
|
||||
#if defined(__APPLE__)
|
||||
static std::atomic<sigaction_cb> previous_sigbus_action;
|
||||
#endif // __APPLE__
|
||||
|
||||
void TrapWebAssemblyOrContinue(int signo, siginfo_t* info, void* ucontext) {
|
||||
if (!v8::TryHandleWebAssemblyTrapPosix(signo, info, ucontext)) {
|
||||
#if defined(__APPLE__)
|
||||
sigaction_cb prev = signo == SIGBUS ? previous_sigbus_action.load()
|
||||
: previous_sigsegv_action.load();
|
||||
#else
|
||||
sigaction_cb prev = previous_sigsegv_action.load();
|
||||
#endif // __APPLE__
|
||||
if (prev != nullptr) {
|
||||
prev(signo, info, ucontext);
|
||||
} else {
|
||||
@ -395,6 +404,15 @@ void RegisterSignalHandler(int signal,
|
||||
previous_sigsegv_action.store(handler);
|
||||
return;
|
||||
}
|
||||
// TODO(align behavior between macos and other in next major version)
|
||||
#if defined(__APPLE__)
|
||||
if (signal == SIGBUS) {
|
||||
CHECK(previous_sigbus_action.is_lock_free());
|
||||
CHECK(!reset_handler);
|
||||
previous_sigbus_action.store(handler);
|
||||
return;
|
||||
}
|
||||
#endif // __APPLE__
|
||||
#endif // NODE_USE_V8_WASM_TRAP_HANDLER
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
@ -551,7 +569,7 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) {
|
||||
#else
|
||||
// Tell V8 to disable emitting WebAssembly
|
||||
// memory bounds checks. This means that we have
|
||||
// to catch the SIGSEGV in TrapWebAssemblyOrContinue
|
||||
// to catch the SIGSEGV/SIGBUS in TrapWebAssemblyOrContinue
|
||||
// and pass the signal context to V8.
|
||||
{
|
||||
struct sigaction sa;
|
||||
@ -559,6 +577,10 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) {
|
||||
sa.sa_sigaction = TrapWebAssemblyOrContinue;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
CHECK_EQ(sigaction(SIGSEGV, &sa, nullptr), 0);
|
||||
// TODO(align behavior between macos and other in next major version)
|
||||
#if defined(__APPLE__)
|
||||
CHECK_EQ(sigaction(SIGBUS, &sa, nullptr), 0);
|
||||
#endif
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
V8::EnableWebAssemblyTrapHandler(false);
|
||||
|
BIN
test/fixtures/out-of-bound.wasm
vendored
Normal file
BIN
test/fixtures/out-of-bound.wasm
vendored
Normal file
Binary file not shown.
16
test/fixtures/out-of-bound.wat
vendored
Normal file
16
test/fixtures/out-of-bound.wat
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
(module
|
||||
(type $none_=>_none (func))
|
||||
(memory $0 1)
|
||||
(export "_start" (func $_start))
|
||||
(func $_start
|
||||
memory.size
|
||||
i32.const 64
|
||||
i32.mul
|
||||
i32.const 1024
|
||||
i32.mul
|
||||
i32.const 3
|
||||
i32.sub
|
||||
i32.load
|
||||
drop
|
||||
)
|
||||
)
|
12
test/parallel/test-wasm-memory-out-of-bound.js
Normal file
12
test/parallel/test-wasm-memory-out-of-bound.js
Normal file
@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
const buffer = fixtures.readSync('out-of-bound.wasm');
|
||||
WebAssembly.instantiate(buffer, {}).then(common.mustCall((results) => {
|
||||
assert.throws(() => {
|
||||
results.instance.exports._start();
|
||||
}, WebAssembly.RuntimeError('memory access out of bounds'));
|
||||
}));
|
Loading…
Reference in New Issue
Block a user