summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorhidehiko <hidehiko@chromium.org>2015-04-22 04:17:08 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-22 11:17:23 +0000
commitc1c944e1ee0b100c9717084b50bdd697c6b308d2 (patch)
tree5fad01b6f6df3a999916b053c530903fabca90b2 /sandbox
parent338bf0048faab4c20b0767620c524b9636c31a04 (diff)
downloadchromium_src-c1c944e1ee0b100c9717084b50bdd697c6b308d2.zip
chromium_src-c1c944e1ee0b100c9717084b50bdd697c6b308d2.tar.gz
chromium_src-c1c944e1ee0b100c9717084b50bdd697c6b308d2.tar.bz2
Reland: Introduce sys_sigprocmask and sys_sigaction. (patchset #5 id:160001 of https://codereview.chromium.org/1077143002/)
This CL is relanding the CL https://codereview.chromium.org/1077143002/, which was reverted due to false alarm of the memory sanitizer. Because the memory sanitizer does not know about direct kernel syscall does, so it warns the arguments of the signal handler, unexpectedly. This CL adds the msan unpoisoning to the arguemtns, so that the memory sanitizer should understand it. TEST=Ran sandbox_linux_unittests with msan=1. Ran bots. BUG=358465 CQ_EXTRA_TRYBOTS=tryserver.chromium.linux:linux_chromium_trusty32_rel,linux_arm Review URL: https://codereview.chromium.org/1092153005 Cr-Commit-Position: refs/heads/master@{#326270}
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/linux/BUILD.gn9
-rw-r--r--sandbox/linux/sandbox_linux.gypi10
-rw-r--r--sandbox/linux/sandbox_linux_test_sources.gypi1
-rw-r--r--sandbox/linux/seccomp-bpf/die.cc7
-rw-r--r--sandbox/linux/seccomp-bpf/syscall.h6
-rw-r--r--sandbox/linux/seccomp-bpf/trap.cc42
-rw-r--r--sandbox/linux/seccomp-bpf/trap.h6
-rw-r--r--sandbox/linux/seccomp-bpf/trap_unittest.cc28
-rw-r--r--sandbox/linux/services/credentials.cc10
-rw-r--r--sandbox/linux/services/syscall_wrappers.cc61
-rw-r--r--sandbox/linux/services/syscall_wrappers.h12
-rw-r--r--sandbox/linux/services/syscall_wrappers_unittest.cc14
-rw-r--r--sandbox/linux/system_headers/android_arm_ucontext.h32
-rw-r--r--sandbox/linux/system_headers/android_ucontext.h28
-rw-r--r--sandbox/linux/system_headers/arm64_linux_ucontext.h (renamed from sandbox/linux/system_headers/android_arm64_ucontext.h)6
-rw-r--r--sandbox/linux/system_headers/arm_linux_ucontext.h67
-rw-r--r--sandbox/linux/system_headers/i386_linux_ucontext.h (renamed from sandbox/linux/system_headers/android_i386_ucontext.h)16
-rw-r--r--sandbox/linux/system_headers/linux_signal.h73
-rw-r--r--sandbox/linux/system_headers/linux_ucontext.h28
-rw-r--r--sandbox/linux/system_headers/mips_linux_ucontext.h (renamed from sandbox/linux/system_headers/android_mips_ucontext.h)6
-rw-r--r--sandbox/linux/system_headers/x86_64_linux_ucontext.h (renamed from sandbox/linux/system_headers/android_x86_64_ucontext.h)6
21 files changed, 356 insertions, 112 deletions
diff --git a/sandbox/linux/BUILD.gn b/sandbox/linux/BUILD.gn
index 21f856b..c42520e 100644
--- a/sandbox/linux/BUILD.gn
+++ b/sandbox/linux/BUILD.gn
@@ -288,15 +288,16 @@ component("sandbox_services") {
source_set("sandbox_services_headers") {
sources = [
- "system_headers/android_arm64_ucontext.h",
- "system_headers/android_arm_ucontext.h",
- "system_headers/android_i386_ucontext.h",
- "system_headers/android_ucontext.h",
"system_headers/arm64_linux_syscalls.h",
+ "system_headers/arm64_linux_ucontext.h",
"system_headers/arm_linux_syscalls.h",
+ "system_headers/arm_linux_ucontext.h",
+ "system_headers/i386_linux_ucontext.h",
"system_headers/linux_futex.h",
"system_headers/linux_seccomp.h",
+ "system_headers/linux_signal.h",
"system_headers/linux_syscalls.h",
+ "system_headers/linux_ucontext.h",
"system_headers/x86_32_linux_syscalls.h",
"system_headers/x86_64_linux_syscalls.h",
]
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 1cf3b2d..7724223 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -278,18 +278,18 @@
{ 'target_name': 'sandbox_services_headers',
'type': 'none',
'sources': [
- 'system_headers/android_arm64_ucontext.h',
- 'system_headers/android_arm_ucontext.h',
- 'system_headers/android_i386_ucontext.h',
- 'system_headers/android_mips_ucontext.h',
- 'system_headers/android_ucontext.h',
'system_headers/arm64_linux_syscalls.h',
+ 'system_headers/arm64_linux_ucontext.h',
'system_headers/arm_linux_syscalls.h',
+ 'system_headers/arm_linux_ucontext.h',
'system_headers/capability.h',
+ 'system_headers/i386_linux_ucontext.h',
'system_headers/linux_futex.h',
'system_headers/linux_seccomp.h',
'system_headers/linux_syscalls.h',
+ 'system_headers/linux_ucontext.h',
'system_headers/mips_linux_syscalls.h',
+ 'system_headers/mips_linux_ucontext.h',
'system_headers/x86_32_linux_syscalls.h',
'system_headers/x86_64_linux_syscalls.h',
],
diff --git a/sandbox/linux/sandbox_linux_test_sources.gypi b/sandbox/linux/sandbox_linux_test_sources.gypi
index c558a0d..ce7817d 100644
--- a/sandbox/linux/sandbox_linux_test_sources.gypi
+++ b/sandbox/linux/sandbox_linux_test_sources.gypi
@@ -53,6 +53,7 @@
'seccomp-bpf/errorcode_unittest.cc',
'seccomp-bpf/sandbox_bpf_unittest.cc',
'seccomp-bpf/syscall_unittest.cc',
+ 'seccomp-bpf/trap_unittest.cc',
],
}],
[ 'compile_credentials==1', {
diff --git a/sandbox/linux/seccomp-bpf/die.cc b/sandbox/linux/seccomp-bpf/die.cc
index 777c9d1..3baf1f1 100644
--- a/sandbox/linux/seccomp-bpf/die.cc
+++ b/sandbox/linux/seccomp-bpf/die.cc
@@ -16,6 +16,8 @@
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "sandbox/linux/seccomp-bpf/syscall.h"
+#include "sandbox/linux/services/syscall_wrappers.h"
+#include "sandbox/linux/system_headers/linux_signal.h"
namespace sandbox {
@@ -32,7 +34,10 @@ void Die::ExitGroup() {
// to a defined state; but we have not way to verify whether we actually
// succeeded in doing so. Nonetheless, triggering a fatal signal could help
// us terminate.
- signal(SIGSEGV, SIG_DFL);
+ struct sigaction sa = {};
+ sa.sa_handler = LINUX_SIG_DFL;
+ sa.sa_flags = LINUX_SA_RESTART;
+ sys_sigaction(LINUX_SIGSEGV, &sa, nullptr);
Syscall::Call(__NR_prctl, PR_SET_DUMPABLE, (void*)0, (void*)0, (void*)0);
if (*(volatile char*)0) {
}
diff --git a/sandbox/linux/seccomp-bpf/syscall.h b/sandbox/linux/seccomp-bpf/syscall.h
index dfb44eb..ccfc88d 100644
--- a/sandbox/linux/seccomp-bpf/syscall.h
+++ b/sandbox/linux/seccomp-bpf/syscall.h
@@ -9,13 +9,9 @@
#include <stdint.h>
#include "base/macros.h"
+#include "sandbox/linux/system_headers/linux_signal.h"
#include "sandbox/sandbox_export.h"
-// Android's signal.h doesn't define ucontext etc.
-#if defined(OS_ANDROID)
-#include "sandbox/linux/system_headers/android_ucontext.h"
-#endif
-
namespace sandbox {
// This purely static class can be used to perform system calls with some
diff --git a/sandbox/linux/seccomp-bpf/trap.cc b/sandbox/linux/seccomp-bpf/trap.cc
index 145e624..b61ae74 100644
--- a/sandbox/linux/seccomp-bpf/trap.cc
+++ b/sandbox/linux/seccomp-bpf/trap.cc
@@ -12,17 +12,15 @@
#include <algorithm>
#include <limits>
+#include "base/compiler_specific.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "sandbox/linux/bpf_dsl/seccomp_macros.h"
#include "sandbox/linux/seccomp-bpf/die.h"
#include "sandbox/linux/seccomp-bpf/syscall.h"
+#include "sandbox/linux/services/syscall_wrappers.h"
#include "sandbox/linux/system_headers/linux_seccomp.h"
-
-// Android's signal.h doesn't define ucontext etc.
-#if defined(OS_ANDROID)
-#include "sandbox/linux/system_headers/android_ucontext.h"
-#endif
+#include "sandbox/linux/system_headers/linux_signal.h"
namespace {
@@ -53,13 +51,13 @@ const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING";
// possibly even worse.
bool GetIsInSigHandler(const ucontext_t* ctx) {
// Note: on Android, sigismember does not take a pointer to const.
- return sigismember(const_cast<sigset_t*>(&ctx->uc_sigmask), SIGBUS);
+ return sigismember(const_cast<sigset_t*>(&ctx->uc_sigmask), LINUX_SIGBUS);
}
void SetIsInSigHandler() {
sigset_t mask;
- if (sigemptyset(&mask) || sigaddset(&mask, SIGBUS) ||
- sigprocmask(SIG_BLOCK, &mask, NULL)) {
+ if (sigemptyset(&mask) || sigaddset(&mask, LINUX_SIGBUS) ||
+ sandbox::sys_sigprocmask(LINUX_SIG_BLOCK, &mask, NULL)) {
SANDBOX_DIE("Failed to block SIGBUS");
}
}
@@ -82,10 +80,13 @@ Trap::Trap()
has_unsafe_traps_(false) {
// Set new SIGSYS handler
struct sigaction sa = {};
- sa.sa_sigaction = SigSysAction;
- sa.sa_flags = SA_SIGINFO | SA_NODEFER;
- struct sigaction old_sa;
- if (sigaction(SIGSYS, &sa, &old_sa) < 0) {
+ // In some toolchain, sa_sigaction is not declared in struct sigaction.
+ // So, here cast the pointer to the sa_handler's type. This works because
+ // |sa_handler| and |sa_sigaction| shares the same memory.
+ sa.sa_handler = reinterpret_cast<void (*)(int)>(SigSysAction);
+ sa.sa_flags = LINUX_SA_SIGINFO | LINUX_SA_NODEFER;
+ struct sigaction old_sa = {};
+ if (sys_sigaction(LINUX_SIGSYS, &sa, &old_sa) < 0) {
SANDBOX_DIE("Failed to configure SIGSYS handler");
}
@@ -99,8 +100,8 @@ Trap::Trap()
// Unmask SIGSYS
sigset_t mask;
- if (sigemptyset(&mask) || sigaddset(&mask, SIGSYS) ||
- sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
+ if (sigemptyset(&mask) || sigaddset(&mask, LINUX_SIGSYS) ||
+ sys_sigprocmask(LINUX_SIG_UNBLOCK, &mask, NULL)) {
SANDBOX_DIE("Failed to configure SIGSYS handler");
}
}
@@ -120,7 +121,14 @@ bpf_dsl::TrapRegistry* Trap::Registry() {
return global_trap_;
}
-void Trap::SigSysAction(int nr, siginfo_t* info, void* void_context) {
+void Trap::SigSysAction(int nr, LinuxSigInfo* info, void* void_context) {
+ if (info) {
+ MSAN_UNPOISON(info, sizeof(*info));
+ }
+ if (void_context) {
+ MSAN_UNPOISON(void_context, sizeof(ucontext_t));
+ }
+
if (!global_trap_) {
RAW_SANDBOX_DIE(
"This can't happen. Found no global singleton instance "
@@ -129,7 +137,7 @@ void Trap::SigSysAction(int nr, siginfo_t* info, void* void_context) {
global_trap_->SigSys(nr, info, void_context);
}
-void Trap::SigSys(int nr, siginfo_t* info, void* void_context) {
+void Trap::SigSys(int nr, LinuxSigInfo* info, void* void_context) {
// Signal handlers should always preserve "errno". Otherwise, we could
// trigger really subtle bugs.
const int old_errno = errno;
@@ -137,7 +145,7 @@ void Trap::SigSys(int nr, siginfo_t* info, void* void_context) {
// Various sanity checks to make sure we actually received a signal
// triggered by a BPF filter. If something else triggered SIGSYS
// (e.g. kill()), there is really nothing we can do with this signal.
- if (nr != SIGSYS || info->si_code != SYS_SECCOMP || !void_context ||
+ if (nr != LINUX_SIGSYS || info->si_code != SYS_SECCOMP || !void_context ||
info->si_errno <= 0 ||
static_cast<size_t>(info->si_errno) > trap_array_size_) {
// ATI drivers seem to send SIGSYS, so this cannot be FATAL.
diff --git a/sandbox/linux/seccomp-bpf/trap.h b/sandbox/linux/seccomp-bpf/trap.h
index 4073bfe..bbddeb7 100644
--- a/sandbox/linux/seccomp-bpf/trap.h
+++ b/sandbox/linux/seccomp-bpf/trap.h
@@ -5,13 +5,13 @@
#ifndef SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__
#define SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__
-#include <signal.h>
#include <stdint.h>
#include <map>
#include "base/macros.h"
#include "sandbox/linux/bpf_dsl/trap_registry.h"
+#include "sandbox/linux/system_headers/linux_signal.h"
#include "sandbox/sandbox_export.h"
namespace sandbox {
@@ -57,11 +57,11 @@ class SANDBOX_EXPORT Trap : public bpf_dsl::TrapRegistry {
// break subsequent system calls that trigger a SIGSYS.
~Trap() = delete;
- static void SigSysAction(int nr, siginfo_t* info, void* void_context);
+ static void SigSysAction(int nr, LinuxSigInfo* info, void* void_context);
// Make sure that SigSys is not inlined in order to get slightly better crash
// dumps.
- void SigSys(int nr, siginfo_t* info, void* void_context)
+ void SigSys(int nr, LinuxSigInfo* info, void* void_context)
__attribute__((noinline));
// We have a global singleton that handles all of our SIGSYS traps. This
// variable must never be deallocated after it has been set up initially, as
diff --git a/sandbox/linux/seccomp-bpf/trap_unittest.cc b/sandbox/linux/seccomp-bpf/trap_unittest.cc
new file mode 100644
index 0000000..99f94bf
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/trap_unittest.cc
@@ -0,0 +1,28 @@
+// Copyright 2015 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 "sandbox/linux/seccomp-bpf/trap.h"
+
+#include <signal.h>
+
+#include "sandbox/linux/tests/unit_tests.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace sandbox {
+namespace {
+
+SANDBOX_TEST_ALLOW_NOISE(Trap, SigSysAction) {
+ // This creates a global Trap instance, and registers the signal handler
+ // (Trap::SigSysAction).
+ Trap::Registry();
+
+ // Send SIGSYS to self. If signal handler (SigSysAction) is not registered,
+ // the process will be terminated with status code -SIGSYS.
+ // Note that, SigSysAction handler would output an error message
+ // "Unexpected SIGSYS received." so it is necessary to allow the noise.
+ raise(SIGSYS);
+}
+
+} // namespace
+} // namespace sandbox
diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc
index b562d8b..35bb4dc 100644
--- a/sandbox/linux/services/credentials.cc
+++ b/sandbox/linux/services/credentials.cc
@@ -27,16 +27,12 @@
#include "sandbox/linux/services/syscall_wrappers.h"
#include "sandbox/linux/services/thread_helpers.h"
#include "sandbox/linux/system_headers/capability.h"
+#include "sandbox/linux/system_headers/linux_signal.h"
namespace sandbox {
namespace {
-// Signal ABI for some toolchain is incompatible with Linux's. In particular,
-// PNaCl toolchain defines SIGCHLD = 20. So, here, directly define Linux's
-// value.
-const int kLinuxSIGCHLD = 17;
-
bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; }
// Checks that the set of RES-uids and the set of RES-gids have
@@ -96,8 +92,8 @@ bool ChrootToSafeEmptyDir() {
#endif
pid = clone(ChrootToSelfFdinfo, stack,
- CLONE_VM | CLONE_VFORK | CLONE_FS | kLinuxSIGCHLD,
- nullptr, nullptr, nullptr, nullptr);
+ CLONE_VM | CLONE_VFORK | CLONE_FS | LINUX_SIGCHLD, nullptr,
+ nullptr, nullptr, nullptr);
PCHECK(pid != -1);
int status = -1;
diff --git a/sandbox/linux/services/syscall_wrappers.cc b/sandbox/linux/services/syscall_wrappers.cc
index e793fad..0366051 100644
--- a/sandbox/linux/services/syscall_wrappers.cc
+++ b/sandbox/linux/services/syscall_wrappers.cc
@@ -12,12 +12,14 @@
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
+#include <cstring>
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/third_party/valgrind/valgrind.h"
#include "build/build_config.h"
#include "sandbox/linux/system_headers/capability.h"
+#include "sandbox/linux/system_headers/linux_signal.h"
#include "sandbox/linux/system_headers/linux_syscalls.h"
namespace sandbox {
@@ -137,4 +139,63 @@ int sys_unshare(int flags) {
return syscall(__NR_unshare, flags);
}
+int sys_sigprocmask(int how, const sigset_t* set, decltype(nullptr) oldset) {
+ // In some toolchain (in particular Android and PNaCl toolchain),
+ // sigset_t is 32 bits, but Linux ABI requires 64 bits.
+ uint64_t linux_value = 0;
+ std::memcpy(&linux_value, set, std::min(sizeof(sigset_t), sizeof(uint64_t)));
+ return syscall(__NR_rt_sigprocmask, how, &linux_value, nullptr,
+ sizeof(linux_value));
+}
+
+// struct sigaction is different ABI from the Linux's.
+struct KernelSigAction {
+ void (*kernel_handler)(int);
+ uint32_t sa_flags;
+ void (*sa_restorer)(void);
+ uint64_t sa_mask;
+};
+
+// On X86_64 arch, it is necessary to set sa_restorer always.
+#if defined(ARCH_CPU_X86_64)
+#if !defined(SA_RESTORER)
+#define SA_RESTORER 0x04000000
+#endif
+
+static void sys_rt_sigreturn() {
+ syscall(__NR_rt_sigreturn);
+}
+#endif
+
+int sys_sigaction(int signum,
+ const struct sigaction* act,
+ struct sigaction* oldact) {
+ KernelSigAction kernel_act = {};
+ if (act) {
+ kernel_act.kernel_handler = act->sa_handler;
+ std::memcpy(&kernel_act.sa_mask, &act->sa_mask,
+ std::min(sizeof(kernel_act.sa_mask), sizeof(act->sa_mask)));
+ kernel_act.sa_flags = act->sa_flags;
+
+#if defined(ARCH_CPU_X86_64)
+ if (!(kernel_act.sa_flags & SA_RESTORER)) {
+ kernel_act.sa_flags |= SA_RESTORER;
+ kernel_act.sa_restorer = sys_rt_sigreturn;
+ }
+#endif
+ }
+
+ KernelSigAction kernel_oldact = {};
+ int result = syscall(__NR_rt_sigaction, signum, act ? &kernel_act : nullptr,
+ oldact ? &kernel_oldact : nullptr, sizeof(uint64_t));
+ if (result == 0 && oldact) {
+ oldact->sa_handler = kernel_oldact.kernel_handler;
+ sigemptyset(&oldact->sa_mask);
+ std::memcpy(&oldact->sa_mask, &kernel_oldact.sa_mask,
+ std::min(sizeof(kernel_act.sa_mask), sizeof(act->sa_mask)));
+ oldact->sa_flags = kernel_oldact.sa_flags;
+ }
+ return result;
+}
+
} // namespace sandbox
diff --git a/sandbox/linux/services/syscall_wrappers.h b/sandbox/linux/services/syscall_wrappers.h
index 4558adf..581425a 100644
--- a/sandbox/linux/services/syscall_wrappers.h
+++ b/sandbox/linux/services/syscall_wrappers.h
@@ -5,6 +5,7 @@
#ifndef SANDBOX_LINUX_SERVICES_SYSCALL_WRAPPERS_H_
#define SANDBOX_LINUX_SERVICES_SYSCALL_WRAPPERS_H_
+#include <signal.h>
#include <stdint.h>
#include <sys/types.h>
@@ -66,6 +67,17 @@ SANDBOX_EXPORT int sys_chroot(const char* path);
// Some libcs do not expose a unshare wrapper.
SANDBOX_EXPORT int sys_unshare(int flags);
+// Some libcs do not expose a sigprocmask. Note that oldset must be a nullptr,
+// because of some ABI gap between toolchain's and Linux's.
+SANDBOX_EXPORT int sys_sigprocmask(int how,
+ const sigset_t* set,
+ decltype(nullptr) oldset);
+
+// Some libcs do not expose a sigaction().
+SANDBOX_EXPORT int sys_sigaction(int signum,
+ const struct sigaction* act,
+ struct sigaction* oldact);
+
} // namespace sandbox
#endif // SANDBOX_LINUX_SERVICES_SYSCALL_WRAPPERS_H_
diff --git a/sandbox/linux/services/syscall_wrappers_unittest.cc b/sandbox/linux/services/syscall_wrappers_unittest.cc
index 6a70beb..1878ff3 100644
--- a/sandbox/linux/services/syscall_wrappers_unittest.cc
+++ b/sandbox/linux/services/syscall_wrappers_unittest.cc
@@ -8,11 +8,13 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <cstring>
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/third_party/valgrind/valgrind.h"
#include "build/build_config.h"
+#include "sandbox/linux/system_headers/linux_signal.h"
#include "sandbox/linux/tests/test_utils.h"
#include "sandbox/linux/tests/unit_tests.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -80,6 +82,18 @@ TEST(SyscallWrappers, GetRESGid) {
EXPECT_EQ(sgid, sys_sgid);
}
+TEST(SyscallWrappers, LinuxSigSet) {
+ sigset_t sigset;
+ ASSERT_EQ(0, sigemptyset(&sigset));
+ ASSERT_EQ(0, sigaddset(&sigset, LINUX_SIGSEGV));
+ ASSERT_EQ(0, sigaddset(&sigset, LINUX_SIGBUS));
+ uint64_t linux_sigset = 0;
+ std::memcpy(&linux_sigset, &sigset,
+ std::min(sizeof(sigset), sizeof(linux_sigset)));
+ EXPECT_EQ((1ULL << (LINUX_SIGSEGV - 1)) | (1ULL << (LINUX_SIGBUS - 1)),
+ linux_sigset);
+}
+
} // namespace
} // namespace sandbox
diff --git a/sandbox/linux/system_headers/android_arm_ucontext.h b/sandbox/linux/system_headers/android_arm_ucontext.h
deleted file mode 100644
index a380499..0000000
--- a/sandbox/linux/system_headers/android_arm_ucontext.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 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 SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_ARM_UCONTEXT_H_
-#define SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_ARM_UCONTEXT_H_
-
-#if !defined(__BIONIC_HAVE_UCONTEXT_T)
-#include <asm/sigcontext.h>
-
-// We also need greg_t for the sandbox, include it in this header as well.
-typedef unsigned long greg_t;
-
-//typedef unsigned long sigset_t;
-typedef struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- struct sigcontext uc_mcontext;
- sigset_t uc_sigmask;
- /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
- int __not_used[32 - (sizeof (sigset_t) / sizeof (int))];
- /* Last for extensibility. Eight byte aligned because some
- coprocessors require eight byte alignment. */
- unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
-} ucontext_t;
-
-#else
-#include <sys/ucontext.h>
-#endif // __BIONIC_HAVE_UCONTEXT_T
-
-#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_ARM_UCONTEXT_H_
diff --git a/sandbox/linux/system_headers/android_ucontext.h b/sandbox/linux/system_headers/android_ucontext.h
deleted file mode 100644
index 8e873be..0000000
--- a/sandbox/linux/system_headers/android_ucontext.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2013 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 SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_UCONTEXT_H_
-#define SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_UCONTEXT_H_
-
-#if defined(__ANDROID__)
-
-#if defined(__arm__)
-#include "sandbox/linux/system_headers/android_arm_ucontext.h"
-#elif defined(__i386__)
-#include "sandbox/linux/system_headers/android_i386_ucontext.h"
-#elif defined(__x86_64__)
-#include "sandbox/linux/system_headers/android_x86_64_ucontext.h"
-#elif defined(__mips__)
-#include "sandbox/linux/system_headers/android_mips_ucontext.h"
-#elif defined(__aarch64__)
-#include "sandbox/linux/system_headers/android_arm64_ucontext.h"
-#else
-#error "No support for your architecture in Android header"
-#endif
-
-#else // __ANDROID__
-#error "Android header file included on non Android."
-#endif // __ANDROID__
-
-#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_UCONTEXT_H_
diff --git a/sandbox/linux/system_headers/android_arm64_ucontext.h b/sandbox/linux/system_headers/arm64_linux_ucontext.h
index df2b66a..46e0407 100644
--- a/sandbox/linux/system_headers/android_arm64_ucontext.h
+++ b/sandbox/linux/system_headers/arm64_linux_ucontext.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_ARM64_UCONTEXT_H_
-#define SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_ARM64_UCONTEXT_H_
+#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_ARM64_LINUX_UCONTEXT_H_
+#define SANDBOX_LINUX_SYSTEM_HEADERS_ARM64_LINUX_UCONTEXT_H_
#if !defined(__BIONIC_HAVE_UCONTEXT_T)
#include <asm/sigcontext.h>
@@ -26,4 +26,4 @@ struct ucontext_t {
#include <sys/ucontext.h>
#endif // __BIONIC_HAVE_UCONTEXT_T
-#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_ARM64_UCONTEXT_H_
+#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ARM64_LINUX_UCONTEXT_H_
diff --git a/sandbox/linux/system_headers/arm_linux_ucontext.h b/sandbox/linux/system_headers/arm_linux_ucontext.h
new file mode 100644
index 0000000..0eb723a
--- /dev/null
+++ b/sandbox/linux/system_headers/arm_linux_ucontext.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2012 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 SANDBOX_LINUX_SYSTEM_HEADERS_ARM_LINUX_UCONTEXT_H_
+#define SANDBOX_LINUX_SYSTEM_HEADERS_ARM_LINUX_UCONTEXT_H_
+
+#if !defined(__BIONIC_HAVE_UCONTEXT_T)
+#if !defined(__native_client_nonsfi__)
+#include <asm/sigcontext.h>
+#else
+// In PNaCl toolchain, sigcontext and stack_t is not defined. So here declare
+// them.
+struct sigcontext {
+ unsigned long trap_no;
+ unsigned long error_code;
+ unsigned long oldmask;
+ unsigned long arm_r0;
+ unsigned long arm_r1;
+ unsigned long arm_r2;
+ unsigned long arm_r3;
+ unsigned long arm_r4;
+ unsigned long arm_r5;
+ unsigned long arm_r6;
+ unsigned long arm_r7;
+ unsigned long arm_r8;
+ unsigned long arm_r9;
+ unsigned long arm_r10;
+ unsigned long arm_fp;
+ unsigned long arm_ip;
+ unsigned long arm_sp;
+ unsigned long arm_lr;
+ unsigned long arm_pc;
+ unsigned long arm_cpsr;
+ unsigned long fault_address;
+};
+
+typedef struct sigaltstack {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+#endif
+
+// We also need greg_t for the sandbox, include it in this header as well.
+typedef unsigned long greg_t;
+
+// typedef unsigned long sigset_t;
+typedef struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext* uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask;
+ /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
+ int __not_used[32 - (sizeof(sigset_t) / sizeof(int))];
+ /* Last for extensibility. Eight byte aligned because some
+ coprocessors require eight byte alignment. */
+ unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
+} ucontext_t;
+
+#else
+#include <sys/ucontext.h>
+#endif // __BIONIC_HAVE_UCONTEXT_T
+
+#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ARM_LINUX_UCONTEXT_H_
diff --git a/sandbox/linux/system_headers/android_i386_ucontext.h b/sandbox/linux/system_headers/i386_linux_ucontext.h
index 868016b..61d9f7a 100644
--- a/sandbox/linux/system_headers/android_i386_ucontext.h
+++ b/sandbox/linux/system_headers/i386_linux_ucontext.h
@@ -11,7 +11,16 @@
// except we do use sigset_t for uc_sigmask instead of a custom type.
#if !defined(__BIONIC_HAVE_UCONTEXT_T)
+#if !defined(__native_client_nonsfi__)
#include <asm/sigcontext.h>
+#else
+// In PNaCl toolchain, sigcontext is not defined. So here declare it.
+typedef struct sigaltstack {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+#endif
/* 80-bit floating-point register */
struct _libc_fpreg {
@@ -68,7 +77,12 @@ typedef struct ucontext {
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- sigset_t uc_sigmask;
+ // Android and PNaCl toolchain's sigset_t has only 32 bits, though Linux
+ // ABI requires 64 bits.
+ union {
+ sigset_t uc_sigmask;
+ uint32_t kernel_sigmask[2];
+ };
struct _libc_fpstate __fpregs_mem;
} ucontext_t;
diff --git a/sandbox/linux/system_headers/linux_signal.h b/sandbox/linux/system_headers/linux_signal.h
new file mode 100644
index 0000000..5db7fc5
--- /dev/null
+++ b/sandbox/linux/system_headers/linux_signal.h
@@ -0,0 +1,73 @@
+// Copyright 2015 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 SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SIGNAL_H_
+#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SIGNAL_H_
+
+// NOTE: On some toolchains, signal related ABI is incompatible with Linux's
+// (not undefined, but defined different values and in different memory
+// layouts). So, fill the gap here.
+
+#if defined(__native_client_nonsfi__)
+#if !defined(__i386__) && !defined(__arm__)
+#error "Unsupported platform"
+#endif
+
+#include <signal.h>
+
+#define LINUX_SIGBUS 7 // 10 in PNaCl toolchain.
+#define LINUX_SIGSEGV 11 // 11 in PNaCl toolchain. Defined for consistency.
+#define LINUX_SIGCHLD 17 // 20 in PNaCl toolchain.
+#define LINUX_SIGSYS 31 // 12 in PNaCl toolchain.
+
+#define LINUX_SIG_BLOCK 0 // 1 in PNaCl toolchain.
+#define LINUX_SIG_UNBLOCK 1 // 2 in PNaCl toolchain.
+
+#define LINUX_SA_SIGINFO 4 // 2 in PNaCl toolchain.
+#define LINUX_SA_NODEFER 0x40000000 // Undefined in PNaCl toolchain.
+#define LINUX_SA_RESTART 0x10000000 // Undefined in PNaCl toolchain.
+
+#define LINUX_SIG_DFL 0 // In PNaCl toolchain, unneeded cast is applied.
+
+struct LinuxSigInfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ // Extra data is followed by the |si_code|. The length depends on the
+ // signal number.
+ char _sifields[1];
+};
+
+#include "sandbox/linux/system_headers/linux_ucontext.h"
+
+#else // !defined(__native_client_nonsfi__)
+
+// Just alias the toolchain's value.
+#include <signal.h>
+
+#define LINUX_SIGBUS SIGBUS
+#define LINUX_SIGSEGV SIGSEGV
+#define LINUX_SIGCHLD SIGCHLD
+#define LINUX_SIGSYS SIGSYS
+
+#define LINUX_SIG_BLOCK SIG_BLOCK
+#define LINUX_SIG_UNBLOCK SIG_UNBLOCK
+
+#define LINUX_SA_SIGINFO SA_SIGINFO
+#define LINUX_SA_NODEFER SA_NODEFER
+#define LINUX_SA_RESTART SA_RESTART
+
+#define LINUX_SIG_DFL SIG_DFL
+
+typedef siginfo_t LinuxSigInfo;
+
+#if defined(__ANDROID__)
+// Android's signal.h doesn't define ucontext etc.
+#include "sandbox/linux/system_headers/linux_ucontext.h"
+#endif // defined(__ANDROID__)
+
+#endif // !defined(__native_client_nonsfi__)
+
+#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SIGNAL_H_
diff --git a/sandbox/linux/system_headers/linux_ucontext.h b/sandbox/linux/system_headers/linux_ucontext.h
new file mode 100644
index 0000000..ea4d8a6
--- /dev/null
+++ b/sandbox/linux/system_headers/linux_ucontext.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2013 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 SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_UCONTEXT_H_
+#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_UCONTEXT_H_
+
+#if defined(__ANDROID__) || defined(__native_client_nonsfi__)
+
+#if defined(__arm__)
+#include "sandbox/linux/system_headers/arm_linux_ucontext.h"
+#elif defined(__i386__)
+#include "sandbox/linux/system_headers/i386_linux_ucontext.h"
+#elif defined(__x86_64__)
+#include "sandbox/linux/system_headers/x86_64_linux_ucontext.h"
+#elif defined(__mips__)
+#include "sandbox/linux/system_headers/mips_linux_ucontext.h"
+#elif defined(__aarch64__)
+#include "sandbox/linux/system_headers/arm64_linux_ucontext.h"
+#else
+#error "No support for your architecture in Android or PNaCl header"
+#endif
+
+#else // defined(__ANDROID__) || defined(__native_client_nonsfi__)
+#error "The header file included on non Android and non PNaCl."
+#endif // defined(__ANDROID__) || defined(__native_client_nonsfi__)
+
+#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_UCONTEXT_H_
diff --git a/sandbox/linux/system_headers/android_mips_ucontext.h b/sandbox/linux/system_headers/mips_linux_ucontext.h
index ec3aa63..27b3763 100644
--- a/sandbox/linux/system_headers/android_mips_ucontext.h
+++ b/sandbox/linux/system_headers/mips_linux_ucontext.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_MIPS_UCONTEXT_H_
-#define SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_MIPS_UCONTEXT_H_
+#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_UCONTEXT_H_
+#define SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_UCONTEXT_H_
// This is mostly copied from breakpad (common/android/include/sys/ucontext.h),
// except we do use sigset_t for uc_sigmask instead of a custom type.
@@ -48,4 +48,4 @@ typedef struct ucontext {
#include <sys/ucontext.h>
#endif // __BIONIC_HAVE_UCONTEXT_T
-#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_MIPS_UCONTEXT_H_
+#endif // SANDBOX_LINUX_SYSTEM_HEADERS_MIPS_LINUX_UCONTEXT_H_
diff --git a/sandbox/linux/system_headers/android_x86_64_ucontext.h b/sandbox/linux/system_headers/x86_64_linux_ucontext.h
index 778e6d0..57b8919 100644
--- a/sandbox/linux/system_headers/android_x86_64_ucontext.h
+++ b/sandbox/linux/system_headers/x86_64_linux_ucontext.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_X86_64_UCONTEXT_H_
-#define SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_X86_64_UCONTEXT_H_
+#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_UCONTEXT_H_
+#define SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_UCONTEXT_H_
// We do something compatible with glibc. Hopefully, at some point Android will
// provide that for us, and __BIONIC_HAVE_UCONTEXT_T should be defined.
@@ -85,4 +85,4 @@ typedef struct ucontext {
#include <sys/ucontext.h>
#endif // __BIONIC_HAVE_UCONTEXT_T
-#endif // SANDBOX_LINUX_SYSTEM_HEADERS_ANDROID_X86_64_UCONTEXT_H_
+#endif // SANDBOX_LINUX_SYSTEM_HEADERS_X86_64_LINUX_UCONTEXT_H_