summaryrefslogtreecommitdiffstats
path: root/components/nacl
diff options
context:
space:
mode:
Diffstat (limited to 'components/nacl')
-rw-r--r--components/nacl/loader/nacl_helper_linux.cc4
-rw-r--r--components/nacl/loader/nonsfi/DEPS2
-rw-r--r--components/nacl/loader/nonsfi/irt_exception_handling.cc106
-rw-r--r--components/nacl/loader/nonsfi/irt_exception_handling.h16
-rw-r--r--components/nacl/loader/nonsfi/irt_interfaces.cc1
-rw-r--r--components/nacl/loader/nonsfi/irt_interfaces.h1
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