Chromium Code Reviews| 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 c25d6cf61141fceb8c933b0581cf2c57ac5d7dd6..ccc5a863dc7919c120a9b00ec43610b98fe07a6f 100644 |
| --- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc |
| +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc |
| @@ -28,6 +28,8 @@ |
| #include "base/macros.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/posix/eintr_wrapper.h" |
| +#include "base/synchronization/waitable_event.h" |
| +#include "base/threading/thread.h" |
| #include "build/build_config.h" |
| #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
| #include "sandbox/linux/seccomp-bpf/syscall.h" |
| @@ -151,16 +153,19 @@ class BlacklistNanosleepPolicy : public SandboxBPFPolicy { |
| } |
| } |
| + static void AssertNanosleepFails() { |
| + const struct timespec ts = {0, 0}; |
| + errno = 0; |
| + BPF_ASSERT(HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL)) == -1); |
| + BPF_ASSERT(errno == EACCES); |
| + } |
| + |
| private: |
| DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); |
| }; |
| BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { |
| - // nanosleep() should be denied |
| - const struct timespec ts = {0, 0}; |
| - errno = 0; |
| - BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| - BPF_ASSERT(errno == EACCES); |
| + BlacklistNanosleepPolicy::AssertNanosleepFails(); |
| } |
| // Now do a simple whitelist test |
| @@ -2145,6 +2150,86 @@ BPF_TEST_C(SandboxBPF, Pread64, TrapPread64Policy) { |
| #endif // !defined(OS_ANDROID) |
| +void* TsyncApplyToTwoThreadsFunc(void* cond_ptr) { |
| + base::WaitableEvent* event = static_cast<base::WaitableEvent*>(cond_ptr); |
| + |
| + // Wait for the main thread to signal that the filter has been applied. |
| + if (!event->IsSignaled()) { |
| + event->Wait(); |
| + } |
| + |
| + BPF_ASSERT(event->IsSignaled()); |
| + |
| + BlacklistNanosleepPolicy::AssertNanosleepFails(); |
| + |
| + return NULL; |
| +} |
| + |
| +SANDBOX_TEST(SandboxBPF, Tsync) { |
| + if (SandboxBPF::SupportsSeccompThreadFilterSynchronization() != |
| + SandboxBPF::STATUS_AVAILABLE) { |
| + return; |
| + } |
| + |
| + base::WaitableEvent event(true, false); |
| + |
| + // Create a thread on which to invoke the blocked syscall. |
| + pthread_t thread; |
| + BPF_ASSERT_EQ(0, |
| + pthread_create(&thread, NULL, &TsyncApplyToTwoThreadsFunc, &event)); |
| + |
| + // Test that nanoseelp success. |
|
jln (very slow on Chromium)
2014/08/21 21:04:42
s/success succeeds.
Robert Sesek
2014/08/25 17:17:26
Done.
|
| + const struct timespec ts = {0, 0}; |
| + BPF_ASSERT(HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL)) == 0); |
|
jln (very slow on Chromium)
2014/08/21 21:04:42
BPF_ASSERT_EQ
Robert Sesek
2014/08/25 17:17:26
Done.
|
| + |
| + // Engage the sandbox. |
| + SandboxBPF sandbox; |
| + sandbox.SetSandboxPolicy(new BlacklistNanosleepPolicy()); |
| + BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); |
| + |
| + // This thread should have the filter applied as well. |
| + BlacklistNanosleepPolicy::AssertNanosleepFails(); |
| + |
| + // Signal the condition to invoke the system call. |
| + event.Signal(); |
| + |
| + // Wait for the thread to finish. |
| + BPF_ASSERT_EQ(0, pthread_join(thread, NULL)); |
| +} |
| + |
| +class AllowAllPolicy : public SandboxBPFPolicy { |
| + public: |
| + AllowAllPolicy() : SandboxBPFPolicy() {} |
| + ~AllowAllPolicy() {} |
| + |
| + |
| + virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| + int sysno) const OVERRIDE { |
| + return ErrorCode(ErrorCode::ERR_ALLOWED); |
| + } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); |
| +}; |
| + |
| +SANDBOX_DEATH_TEST(SandboxBPF, StartMultiThreadedAsSingleThreaded, |
| + DEATH_MESSAGE("Cannot start sandbox; process is already multi-threaded")) { |
| + base::Thread thread("sandbox.linux.StartMultiThreadedAsSingleThreaded"); |
| + BPF_ASSERT(thread.Start()); |
| + |
| + SandboxBPF sandbox; |
| + sandbox.SetSandboxPolicy(new AllowAllPolicy()); |
| + BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |
| +} |
| + |
| +SANDBOX_DEATH_TEST(SandboxBPF, StartSingleThreadedAsMultiThreaded, |
| + DEATH_MESSAGE("Cannot start sandbox; process is not multi-threaded when " |
| + "reported as such")) { |
| + SandboxBPF sandbox; |
| + sandbox.SetSandboxPolicy(new AllowAllPolicy()); |
| + BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); |
| +} |
| + |
| } // namespace |
| } // namespace sandbox |