diff options
Diffstat (limited to 'components/nacl')
-rw-r--r-- | components/nacl/loader/nacl_helper_linux.cc | 4 | ||||
-rw-r--r-- | components/nacl/loader/nonsfi/DEPS | 2 | ||||
-rw-r--r-- | components/nacl/loader/nonsfi/irt_exception_handling.cc | 106 | ||||
-rw-r--r-- | components/nacl/loader/nonsfi/irt_exception_handling.h | 16 | ||||
-rw-r--r-- | components/nacl/loader/nonsfi/irt_interfaces.cc | 1 | ||||
-rw-r--r-- | components/nacl/loader/nonsfi/irt_interfaces.h | 1 |
6 files changed, 130 insertions, 0 deletions
diff --git a/components/nacl/loader/nacl_helper_linux.cc b/components/nacl/loader/nacl_helper_linux.cc index 68d0ff6..1fbfdad 100644 --- a/components/nacl/loader/nacl_helper_linux.cc +++ b/components/nacl/loader/nacl_helper_linux.cc @@ -32,6 +32,7 @@ #include "base/rand_util.h" #include "components/nacl/common/nacl_switches.h" #include "components/nacl/loader/nacl_listener.h" +#include "components/nacl/loader/nonsfi/irt_exception_handling.h" #include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h" #include "content/public/common/content_descriptors.h" #include "content/public/common/zygote_fork_delegate_linux.h" @@ -82,6 +83,9 @@ void BecomeNaClLoader(const std::vector<int>& child_fds, base::GlobalDescriptors::kBaseDescriptor + kSandboxIPCChannel; ReplaceFDWithDummy(sandbox_ipc_channel); + + // Install crash signal handlers before disallowing system calls. + nacl::nonsfi::InitializeSignalHandler(); } // Finish layer-1 sandbox initialization and initialize the layer-2 sandbox. diff --git a/components/nacl/loader/nonsfi/DEPS b/components/nacl/loader/nonsfi/DEPS index 18f97f5..6052a40 100644 --- a/components/nacl/loader/nonsfi/DEPS +++ b/components/nacl/loader/nonsfi/DEPS @@ -1,4 +1,6 @@ include_rules = [ "+ppapi/nacl_irt", "+sandbox/linux/seccomp-bpf-helpers", + "+native_client/src/trusted/service_runtime/nacl_exception.h", + "+native_client/src/trusted/service_runtime/nacl_signal.h", ] diff --git a/components/nacl/loader/nonsfi/irt_exception_handling.cc b/components/nacl/loader/nonsfi/irt_exception_handling.cc new file mode 100644 index 0000000..c6bd26f --- /dev/null +++ b/components/nacl/loader/nonsfi/irt_exception_handling.cc @@ -0,0 +1,106 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <errno.h> +#include <pthread.h> +#include <signal.h> + +#include "components/nacl/loader/nonsfi/irt_interfaces.h" +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/trusted/service_runtime/nacl_exception.h" +#include "native_client/src/trusted/service_runtime/nacl_signal.h" + +namespace nacl { +namespace nonsfi { +namespace { + +// This is NonSFI version of exception handling codebase, NaCl side of +// things resides in: +// native_client/src/trusted/service_runtime/linux/nacl_signal.c +// native_client/src/trusted/service_runtime/sys_exception.c + +// Crash signals to handle. The differences from SFI NaCl are that +// NonSFI NaCl does not use NACL_THREAD_SUSPEND_SIGNAL (==SIGUSR1), +// and SIGSYS is reserved for seccomp-bpf. +const int kSignals[] = { + SIGSTKFLT, + SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV, + // Handle SIGABRT in case someone sends it asynchronously using kill(). + SIGABRT +}; + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +NaClExceptionHandler signal_handler_function_pointer = NULL; + +// Signal handler, responsible for calling the registered handler. +void SignalCatch(int sig, siginfo_t* info, void* uc) { + if (signal_handler_function_pointer) { + NaClSignalContext signal_context; + NaClSignalContextFromHandler(&signal_context, uc); + NaClExceptionFrame exception_frame; + NaClSignalSetUpExceptionFrame(&exception_frame, + &signal_context, + 0 /* context_user_addr, + not useful for NonSFI NaCl. */); + signal_handler_function_pointer(&exception_frame.context); + } + _exit(-1); +} + +int IrtExceptionHandler(NaClExceptionHandler handler, + NaClExceptionHandler* old_handler) { + pthread_mutex_lock(&mutex); + if (old_handler) + *old_handler = signal_handler_function_pointer; + signal_handler_function_pointer = handler; + pthread_mutex_unlock(&mutex); + return 0; +} + +int IrtExceptionStack(void* stack, size_t size) { + // TODO(uekawa): Implement this function so that the exception stack + // actually gets used for running an exception handler. Currently + // we don't switch stack, which means we can't handle stack overflow + // exceptions. + return 0; +} + +int IrtExceptionClearFlag(void) { + // TODO(uekawa): Implement clear_flag() to behave like SFI NaCl's + // implementation, so that a thread can handle a second exception + // after handling a first exception + return ENOSYS; +} + +} // namespace + +const struct nacl_irt_exception_handling kIrtExceptionHandling = { + IrtExceptionHandler, + IrtExceptionStack, + IrtExceptionClearFlag, +}; + +void InitializeSignalHandler() { + struct sigaction sa; + unsigned int a; + + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = SignalCatch; + sa.sa_flags = SA_ONSTACK | SA_SIGINFO; + + // Mask all signals we catch to prevent re-entry. + for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) { + sigaddset(&sa.sa_mask, kSignals[a]); + } + + // Install all handlers. + for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) { + if (sigaction(kSignals[a], &sa, NULL) != 0) + NaClLog(LOG_FATAL, "sigaction to register signals failed.\n"); + } +} + +} // namespace nonsfi +} // namespace nacl diff --git a/components/nacl/loader/nonsfi/irt_exception_handling.h b/components/nacl/loader/nonsfi/irt_exception_handling.h new file mode 100644 index 0000000..b6aafbd --- /dev/null +++ b/components/nacl/loader/nonsfi/irt_exception_handling.h @@ -0,0 +1,16 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_NACL_LOADER_NONSFI_IRT_EXCEPTION_HANDLING_H_ +#define COMPONENTS_NACL_LOADER_NONSFI_IRT_EXCEPTION_HANDLING_H_ + +namespace nacl { +namespace nonsfi { + +void InitializeSignalHandler(); + +} // namespace nonsfi +} // namespace nacl + +#endif // COMPONENTS_NACL_LOADER_NONSFI_IRT_EXCEPTION_HANDLING_H_ diff --git a/components/nacl/loader/nonsfi/irt_interfaces.cc b/components/nacl/loader/nonsfi/irt_interfaces.cc index a8d3285..79bb8f5 100644 --- a/components/nacl/loader/nonsfi/irt_interfaces.cc +++ b/components/nacl/loader/nonsfi/irt_interfaces.cc @@ -31,6 +31,7 @@ const NaClInterfaceTable kIrtInterfaces[] = { NACL_INTERFACE_TABLE(NACL_IRT_CLOCK_v0_1, kIrtClock), NACL_INTERFACE_TABLE(NACL_IRT_PPAPIHOOK_v0_1, kIrtPpapiHook), NACL_INTERFACE_TABLE(NACL_IRT_RANDOM_v0_1, kIrtRandom), + NACL_INTERFACE_TABLE(NACL_IRT_EXCEPTION_HANDLING_v0_1, kIrtExceptionHandling), }; #undef NACL_INTERFACE_TABLE diff --git a/components/nacl/loader/nonsfi/irt_interfaces.h b/components/nacl/loader/nonsfi/irt_interfaces.h index fae2d2d..6d723e6 100644 --- a/components/nacl/loader/nonsfi/irt_interfaces.h +++ b/components/nacl/loader/nonsfi/irt_interfaces.h @@ -24,6 +24,7 @@ extern const struct nacl_irt_tls kIrtTls; extern const struct nacl_irt_clock kIrtClock; extern const struct nacl_irt_ppapihook kIrtPpapiHook; extern const struct nacl_irt_random kIrtRandom; +extern const struct nacl_irt_exception_handling kIrtExceptionHandling; } // namespace nonsfi } // namespace nacl |