Index: sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc |
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc |
index e9bbb344a95e2516cc34e1249eb8eafc3e1f3d49..3d15c7739fb24982ec3d793e1960b3394c82ff8c 100644 |
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc |
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc |
@@ -2,6 +2,8 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include <pthread.h> |
+#include <sched.h> |
#include <sys/syscall.h> |
#include <sys/utsname.h> |
@@ -987,4 +989,57 @@ BPF_DEATH_TEST(SandboxBpf, EqualityWithNegative64bitArguments, |
} |
#endif |
+intptr_t PthreadTrapHandler(const struct arch_seccomp_data& args, void *aux) { |
+ printf("Clone() was called with unexpected arguments\n" |
+ " nr: %d\n" |
+ " 0: 0x%llX\n" |
+ " 1: 0x%llX\n" |
+ " 2: 0x%llX\n" |
+ " 3: 0x%llX\n" |
+ " 4: 0x%llX\n" |
+ " 5: 0x%llX\n", |
+ args.nr, |
+ (long long)args.args[0], (long long)args.args[1], |
+ (long long)args.args[2], (long long)args.args[2], |
+ (long long)args.args[4], (long long)args.args[5]); |
+ return -EPERM; |
+} |
+ |
+ErrorCode PthreadPolicy(int sysno, void *aux) { |
+ if (!Sandbox::IsValidSyscallNumber(sysno)) { |
+ // FIXME: we should really not have to do that in a trivial policy |
+ return ErrorCode(ENOSYS); |
+ } else if (sysno == __NR_clone) { |
+ // We have seen two different valid combinations of flags. Glibc |
+ // uses the more modern flags, sets the TLS from the call to clone(), and |
+ // uses futexes to monitor threads. Android's C run-time library, doesn't |
+ // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
+ return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| |
+ CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS| |
+ CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, |
+ ErrorCode(ErrorCode::ERR_ALLOWED), |
+ Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| |
+ CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED, |
+ ErrorCode(ErrorCode::ERR_ALLOWED), |
+ Sandbox::Trap(PthreadTrapHandler, aux))); |
+ } else { |
+ return ErrorCode(ErrorCode::ERR_ALLOWED); |
+ } |
+} |
+ |
+static void *ThreadFnc(void *arg) { |
+ ++*reinterpret_cast<int *>(arg); |
+ return NULL; |
+} |
+ |
+BPF_TEST(SandboxBpf, Pthread, PthreadPolicy) { |
+ pthread_t thread; |
+ int thread_ran = 0; |
+ BPF_ASSERT(!pthread_create(&thread, NULL, ThreadFnc, &thread_ran)); |
+ BPF_ASSERT(!pthread_join(thread, NULL)); |
+ BPF_ASSERT(thread_ran); |
+} |
+ |
} // namespace |