| Index: sandbox/linux/seccomp-bpf/trap.cc
|
| diff --git a/sandbox/linux/seccomp-bpf/trap.cc b/sandbox/linux/seccomp-bpf/trap.cc
|
| index 145e62469cacca37c07aa40916c1d27795082c11..c09b765d95044c486d7ac61c32a4fda5201c1689 100644
|
| --- a/sandbox/linux/seccomp-bpf/trap.cc
|
| +++ b/sandbox/linux/seccomp-bpf/trap.cc
|
| @@ -5,7 +5,6 @@
|
| #include "sandbox/linux/seccomp-bpf/trap.h"
|
|
|
| #include <errno.h>
|
| -#include <signal.h>
|
| #include <string.h>
|
| #include <sys/syscall.h>
|
|
|
| @@ -17,20 +16,33 @@
|
| #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"
|
| +#include "sandbox/linux/system_headers/linux_signal.h"
|
|
|
| // Android's signal.h doesn't define ucontext etc.
|
| -#if defined(OS_ANDROID)
|
| +#if defined(OS_ANDROID) || defined(OS_NACL_NONSFI)
|
| #include "sandbox/linux/system_headers/android_ucontext.h"
|
| #endif
|
|
|
| namespace {
|
|
|
| -struct arch_sigsys {
|
| - void* ip;
|
| - int nr;
|
| - unsigned int arch;
|
| -};
|
| +// TODO: Where is the best place to put these?
|
| +int linux_sigemptyset(linux_sigset_t* sigset) {
|
| + memset(sigset, 0, sizeof(*sigset));
|
| + return 0;
|
| +}
|
| +
|
| +// TODO: do we need to support 64-bits?
|
| +int linux_sigaddset(linux_sigset_t* sigset, int signum) {
|
| + sigset->sig[0] |= (1 << (signum - 1));
|
| + return 0;
|
| +}
|
| +
|
| +// TODO: do we need to support 64-bits?
|
| +int linux_sigismember(const linux_sigset_t *sigset, int signum) {
|
| + return (sigset->sig[0] >> (signum - 1)) & 1;
|
| +}
|
|
|
| const int kCapacityIncrement = 20;
|
|
|
| @@ -52,20 +64,21 @@ const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING";
|
| // way to mark a signal as allocated. So, the potential for collision is
|
| // 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 linux_sigismember(
|
| + reinterpret_cast<const linux_sigset_t*>(&ctx->uc_sigmask),
|
| + LINUX_SIGBUS);
|
| }
|
|
|
| void SetIsInSigHandler() {
|
| - sigset_t mask;
|
| - if (sigemptyset(&mask) || sigaddset(&mask, SIGBUS) ||
|
| - sigprocmask(SIG_BLOCK, &mask, NULL)) {
|
| + linux_sigset_t mask;
|
| + if (linux_sigemptyset(&mask) || linux_sigaddset(&mask, LINUX_SIGBUS) ||
|
| + sandbox::sys_sigprocmask(LINUX_SIG_BLOCK, &mask, NULL)) {
|
| SANDBOX_DIE("Failed to block SIGBUS");
|
| }
|
| }
|
|
|
| -bool IsDefaultSignalAction(const struct sigaction& sa) {
|
| - if (sa.sa_flags & SA_SIGINFO || sa.sa_handler != SIG_DFL) {
|
| +bool IsDefaultSignalAction(const struct linux_sigaction& sa) {
|
| + if (sa.sa_flags & LINUX_SA_SIGINFO || sa.sa_handler_ != LINUX_SIG_DFL) {
|
| return false;
|
| }
|
| return true;
|
| @@ -81,11 +94,11 @@ Trap::Trap()
|
| trap_array_capacity_(0),
|
| 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) {
|
| + struct linux_sigaction sa = {};
|
| + sa.sa_sigaction_ = SigSysAction;
|
| + sa.sa_flags = LINUX_SA_SIGINFO | LINUX_SA_NODEFER;
|
| + struct linux_sigaction old_sa;
|
| + if (sys_sigaction(LINUX_SIGSYS, &sa, &old_sa) < 0) {
|
| SANDBOX_DIE("Failed to configure SIGSYS handler");
|
| }
|
|
|
| @@ -98,9 +111,9 @@ Trap::Trap()
|
| }
|
|
|
| // Unmask SIGSYS
|
| - sigset_t mask;
|
| - if (sigemptyset(&mask) || sigaddset(&mask, SIGSYS) ||
|
| - sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
|
| + linux_sigset_t mask;
|
| + if (linux_sigemptyset(&mask) || linux_sigaddset(&mask, SIGSYS) ||
|
| + sys_sigprocmask(LINUX_SIG_UNBLOCK, &mask, NULL)) {
|
| SANDBOX_DIE("Failed to configure SIGSYS handler");
|
| }
|
| }
|
| @@ -120,7 +133,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, linux_siginfo_t* info, void* void_context) {
|
| if (!global_trap_) {
|
| RAW_SANDBOX_DIE(
|
| "This can't happen. Found no global singleton instance "
|
| @@ -129,7 +142,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, linux_siginfo_t* info, void* void_context) {
|
| // Signal handlers should always preserve "errno". Otherwise, we could
|
| // trigger really subtle bugs.
|
| const int old_errno = errno;
|
| @@ -137,7 +150,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.
|
|
|