| Index: components/nacl/loader/nonsfi/nonsfi_sandbox.cc
|
| diff --git a/components/nacl/loader/nonsfi/nonsfi_sandbox.cc b/components/nacl/loader/nonsfi/nonsfi_sandbox.cc
|
| index 475c28c28c637f4975287402af9c28b65132117c..c7d14a4522f5afbf075800d45e9ccb96a62ba157 100644
|
| --- a/components/nacl/loader/nonsfi/nonsfi_sandbox.cc
|
| +++ b/components/nacl/loader/nonsfi/nonsfi_sandbox.cc
|
| @@ -22,6 +22,7 @@
|
| #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
|
| #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
|
| #include "sandbox/linux/system_headers/linux_futex.h"
|
| +#include "sandbox/linux/system_headers/linux_signal.h"
|
| #include "sandbox/linux/system_headers/linux_syscalls.h"
|
|
|
| // Chrome OS Daisy (ARM) build environment and PNaCl toolchain do not define
|
| @@ -83,7 +84,11 @@ ResultExpr RestrictClone() {
|
| clone_flags |= CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID;
|
| #endif
|
| const Arg<int> flags(0);
|
| - return If(flags == clone_flags, Allow()).Else(CrashSIGSYSClone());
|
| + // TODO(lhchavez): Add CLONE_PARENT_SETTID unconditionally to the allowed
|
| + // flags after the NaCl roll.
|
| + return If(flags == clone_flags ||
|
| + flags == (clone_flags | CLONE_PARENT_SETTID),
|
| + Allow()).Else(CrashSIGSYSClone());
|
| }
|
|
|
| ResultExpr RestrictFutexOperation() {
|
| @@ -146,6 +151,18 @@ ResultExpr RestrictMmap() {
|
| Allow()).Else(CrashSIGSYS());
|
| }
|
|
|
| +ResultExpr RestrictTgkill(int policy_pid) {
|
| + const Arg<int> tgid(0), tid(1), signum(2);
|
| + // Only sending SIGUSR1 to a thread in the same process is allowed.
|
| + return If(tgid == policy_pid &&
|
| + // Arg does not support a greater-than operator, so two separate
|
| + // checks are needed to ensure tid is positive.
|
| + tid != 0 &&
|
| + (tid & (1u << 31)) == 0 && // tid is non-negative.
|
| + signum == LINUX_SIGUSR1,
|
| + Allow()).Else(CrashSIGSYS());
|
| +}
|
| +
|
| #if !defined(OS_NACL_NONSFI) && (defined(__x86_64__) || defined(__arm__))
|
| ResultExpr RestrictSocketpair() {
|
| // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen.
|
| @@ -211,6 +228,16 @@ void RunSandboxSanityChecks() {
|
|
|
| } // namespace
|
|
|
| +NaClNonSfiBPFSandboxPolicy::NaClNonSfiBPFSandboxPolicy()
|
| + : policy_pid_(getpid()) {
|
| +}
|
| +
|
| +NaClNonSfiBPFSandboxPolicy::~NaClNonSfiBPFSandboxPolicy() {
|
| + // Make sure that this policy is created, used and destroyed by a single
|
| + // process.
|
| + DCHECK_EQ(getpid(), policy_pid_);
|
| +}
|
| +
|
| ResultExpr NaClNonSfiBPFSandboxPolicy::EvaluateSyscall(int sysno) const {
|
| switch (sysno) {
|
| // Allowed syscalls.
|
| @@ -304,6 +331,9 @@ ResultExpr NaClNonSfiBPFSandboxPolicy::EvaluateSyscall(int sysno) const {
|
| #endif
|
| #endif
|
|
|
| + case __NR_tgkill:
|
| + return RestrictTgkill(policy_pid_);
|
| +
|
| case __NR_brk:
|
| // The behavior of brk on Linux is different from other system
|
| // calls. It does not return errno but the current break on
|
|
|