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 |