Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <errno.h> | 5 #include <errno.h> |
| 6 #include <pthread.h> | 6 #include <pthread.h> |
| 7 #include <sched.h> | 7 #include <sched.h> |
| 8 #include <signal.h> | 8 #include <signal.h> |
| 9 #include <sys/prctl.h> | 9 #include <sys/prctl.h> |
| 10 #include <sys/ptrace.h> | 10 #include <sys/ptrace.h> |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #endif | 21 #endif |
| 22 #include <linux/futex.h> | 22 #include <linux/futex.h> |
| 23 | 23 |
| 24 #include <ostream> | 24 #include <ostream> |
| 25 | 25 |
| 26 #include "base/bind.h" | 26 #include "base/bind.h" |
| 27 #include "base/logging.h" | 27 #include "base/logging.h" |
| 28 #include "base/macros.h" | 28 #include "base/macros.h" |
| 29 #include "base/memory/scoped_ptr.h" | 29 #include "base/memory/scoped_ptr.h" |
| 30 #include "base/posix/eintr_wrapper.h" | 30 #include "base/posix/eintr_wrapper.h" |
| 31 #include "base/synchronization/waitable_event.h" | |
| 32 #include "base/threading/thread.h" | |
| 31 #include "build/build_config.h" | 33 #include "build/build_config.h" |
| 32 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" | 34 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
| 33 #include "sandbox/linux/seccomp-bpf/syscall.h" | 35 #include "sandbox/linux/seccomp-bpf/syscall.h" |
| 34 #include "sandbox/linux/seccomp-bpf/trap.h" | 36 #include "sandbox/linux/seccomp-bpf/trap.h" |
| 35 #include "sandbox/linux/seccomp-bpf/verifier.h" | 37 #include "sandbox/linux/seccomp-bpf/verifier.h" |
| 36 #include "sandbox/linux/services/broker_process.h" | 38 #include "sandbox/linux/services/broker_process.h" |
| 37 #include "sandbox/linux/services/linux_syscalls.h" | 39 #include "sandbox/linux/services/linux_syscalls.h" |
| 38 #include "sandbox/linux/tests/scoped_temporary_file.h" | 40 #include "sandbox/linux/tests/scoped_temporary_file.h" |
| 39 #include "sandbox/linux/tests/unit_tests.h" | 41 #include "sandbox/linux/tests/unit_tests.h" |
| 40 #include "testing/gtest/include/gtest/gtest.h" | 42 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { | 146 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
| 145 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 147 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 146 switch (sysno) { | 148 switch (sysno) { |
| 147 case __NR_nanosleep: | 149 case __NR_nanosleep: |
| 148 return ErrorCode(EACCES); | 150 return ErrorCode(EACCES); |
| 149 default: | 151 default: |
| 150 return ErrorCode(ErrorCode::ERR_ALLOWED); | 152 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 151 } | 153 } |
| 152 } | 154 } |
| 153 | 155 |
| 156 static void AssertNanosleepFails() { | |
| 157 const struct timespec ts = {0, 0}; | |
| 158 errno = 0; | |
| 159 BPF_ASSERT(HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL)) == -1); | |
| 160 BPF_ASSERT(errno == EACCES); | |
| 161 } | |
| 162 | |
| 154 private: | 163 private: |
| 155 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); | 164 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); |
| 156 }; | 165 }; |
| 157 | 166 |
| 158 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | 167 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { |
| 159 // nanosleep() should be denied | 168 BlacklistNanosleepPolicy::AssertNanosleepFails(); |
| 160 const struct timespec ts = {0, 0}; | |
| 161 errno = 0; | |
| 162 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | |
| 163 BPF_ASSERT(errno == EACCES); | |
| 164 } | 169 } |
| 165 | 170 |
| 166 // Now do a simple whitelist test | 171 // Now do a simple whitelist test |
| 167 | 172 |
| 168 class WhitelistGetpidPolicy : public SandboxBPFPolicy { | 173 class WhitelistGetpidPolicy : public SandboxBPFPolicy { |
| 169 public: | 174 public: |
| 170 WhitelistGetpidPolicy() {} | 175 WhitelistGetpidPolicy() {} |
| 171 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { | 176 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
| 172 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 177 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 173 switch (sysno) { | 178 switch (sysno) { |
| (...skipping 1964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2138 BPF_ASSERT(FullPread64(temp_file.fd(), | 2143 BPF_ASSERT(FullPread64(temp_file.fd(), |
| 2139 read_test_string, | 2144 read_test_string, |
| 2140 sizeof(read_test_string), | 2145 sizeof(read_test_string), |
| 2141 kLargeOffset)); | 2146 kLargeOffset)); |
| 2142 BPF_ASSERT_EQ(0, memcmp(kTestString, read_test_string, sizeof(kTestString))); | 2147 BPF_ASSERT_EQ(0, memcmp(kTestString, read_test_string, sizeof(kTestString))); |
| 2143 BPF_ASSERT(pread_64_was_forwarded); | 2148 BPF_ASSERT(pread_64_was_forwarded); |
| 2144 } | 2149 } |
| 2145 | 2150 |
| 2146 #endif // !defined(OS_ANDROID) | 2151 #endif // !defined(OS_ANDROID) |
| 2147 | 2152 |
| 2153 void* TsyncApplyToTwoThreadsFunc(void* cond_ptr) { | |
| 2154 base::WaitableEvent* event = static_cast<base::WaitableEvent*>(cond_ptr); | |
| 2155 | |
| 2156 // Wait for the main thread to signal that the filter has been applied. | |
| 2157 if (!event->IsSignaled()) { | |
| 2158 event->Wait(); | |
| 2159 } | |
| 2160 | |
| 2161 BPF_ASSERT(event->IsSignaled()); | |
| 2162 | |
| 2163 BlacklistNanosleepPolicy::AssertNanosleepFails(); | |
| 2164 | |
| 2165 return NULL; | |
| 2166 } | |
| 2167 | |
| 2168 SANDBOX_TEST(SandboxBPF, Tsync) { | |
| 2169 if (SandboxBPF::SupportsSeccompThreadFilterSynchronization() != | |
| 2170 SandboxBPF::STATUS_AVAILABLE) { | |
| 2171 return; | |
| 2172 } | |
| 2173 | |
| 2174 base::WaitableEvent event(true, false); | |
| 2175 | |
| 2176 // Create a thread on which to invoke the blocked syscall. | |
| 2177 pthread_t thread; | |
| 2178 BPF_ASSERT_EQ(0, | |
| 2179 pthread_create(&thread, NULL, &TsyncApplyToTwoThreadsFunc, &event)); | |
| 2180 | |
| 2181 // 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.
| |
| 2182 const struct timespec ts = {0, 0}; | |
| 2183 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.
| |
| 2184 | |
| 2185 // Engage the sandbox. | |
| 2186 SandboxBPF sandbox; | |
| 2187 sandbox.SetSandboxPolicy(new BlacklistNanosleepPolicy()); | |
| 2188 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); | |
| 2189 | |
| 2190 // This thread should have the filter applied as well. | |
| 2191 BlacklistNanosleepPolicy::AssertNanosleepFails(); | |
| 2192 | |
| 2193 // Signal the condition to invoke the system call. | |
| 2194 event.Signal(); | |
| 2195 | |
| 2196 // Wait for the thread to finish. | |
| 2197 BPF_ASSERT_EQ(0, pthread_join(thread, NULL)); | |
| 2198 } | |
| 2199 | |
| 2200 class AllowAllPolicy : public SandboxBPFPolicy { | |
| 2201 public: | |
| 2202 AllowAllPolicy() : SandboxBPFPolicy() {} | |
| 2203 ~AllowAllPolicy() {} | |
| 2204 | |
| 2205 | |
| 2206 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | |
| 2207 int sysno) const OVERRIDE { | |
| 2208 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 2209 } | |
| 2210 | |
| 2211 private: | |
| 2212 DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); | |
| 2213 }; | |
| 2214 | |
| 2215 SANDBOX_DEATH_TEST(SandboxBPF, StartMultiThreadedAsSingleThreaded, | |
| 2216 DEATH_MESSAGE("Cannot start sandbox; process is already multi-threaded")) { | |
| 2217 base::Thread thread("sandbox.linux.StartMultiThreadedAsSingleThreaded"); | |
| 2218 BPF_ASSERT(thread.Start()); | |
| 2219 | |
| 2220 SandboxBPF sandbox; | |
| 2221 sandbox.SetSandboxPolicy(new AllowAllPolicy()); | |
| 2222 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); | |
| 2223 } | |
| 2224 | |
| 2225 SANDBOX_DEATH_TEST(SandboxBPF, StartSingleThreadedAsMultiThreaded, | |
| 2226 DEATH_MESSAGE("Cannot start sandbox; process is not multi-threaded when " | |
| 2227 "reported as such")) { | |
| 2228 SandboxBPF sandbox; | |
| 2229 sandbox.SetSandboxPolicy(new AllowAllPolicy()); | |
| 2230 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); | |
| 2231 } | |
| 2232 | |
| 2148 } // namespace | 2233 } // namespace |
| 2149 | 2234 |
| 2150 } // namespace sandbox | 2235 } // namespace sandbox |
| OLD | NEW |