summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorhidehiko <hidehiko@chromium.org>2015-04-17 07:59:28 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-17 14:59:48 +0000
commit3a315e3246a5191cee27216c09e669ea2d6c33d3 (patch)
treeb4dfc25b3a8f2c89d154947c2a52b7fac46d5155 /sandbox
parentf3bd9b49dc8eecd3352436ea4b83579da12d5364 (diff)
downloadchromium_src-3a315e3246a5191cee27216c09e669ea2d6c33d3.zip
chromium_src-3a315e3246a5191cee27216c09e669ea2d6c33d3.tar.gz
chromium_src-3a315e3246a5191cee27216c09e669ea2d6c33d3.tar.bz2
Introduce sys_sigprocmask and sys_sigaction.
This is preparation of nacl_helper_nonsfi's secompbpf sandbox implementation. PNaCl toolchain's signal ABI is incompatible with Linux's. For example, the length of sigset_t is shoter than Linux's. (Android has also same problem). siginfo_t has different memory layout. Some signal numbers, including SIGBUS, SIGCHLD and SIGSYS, or some signal flags are different. This CL fills the gap, by introducing linux_signal.h and two syscalls, sys_sigprocmask and sys_sigaction. Also, as signal.h provides ucontext_t, but PNaCl toolchain does not provides ucontext_t, this CL re-use the android_ucontext.h (by renaming it to linux_ucontext.h). TEST=Ran bots. BUG=358465 CQ_EXTRA_TRYBOTS=tryserver.chromium.linux:linux_chromium_trusty32_rel,linux_arm Review URL: https://codereview.chromium.org/1077143002 Cr-Commit-Position: refs/heads/master@{#325634}
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/linux/BUILD.gn9
-rw-r--r--sandbox/linux/sandbox_linux.gypi10
-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.cc34
-rw-r--r--sandbox/linux/seccomp-bpf/trap.h6
-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
19 files changed, 319 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/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..79b7569 100644
--- a/sandbox/linux/seccomp-bpf/trap.cc
+++ b/sandbox/linux/seccomp-bpf/trap.cc
@@ -17,12 +17,9 @@
#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 +50,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 +79,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 +99,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 +120,7 @@ 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 (!global_trap_) {
RAW_SANDBOX_DIE(
"This can't happen. Found no global singleton instance "
@@ -129,7 +129,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 +137,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/services/credentials.cc b/sandbox/linux/services/credentials.cc
index 475ce3f..883e396 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_