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. |