Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1069)

Side by Side Diff: sandbox/linux/bpf_dsl/bpf_dsl_more_unittest.cc

Issue 759473002: Linux sandbox: change seccomp detection and initialization. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@refactor_startsandbox
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "sandbox/linux/bpf_dsl/bpf_dsl.h" 5 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <pthread.h> 9 #include <pthread.h>
10 #include <sched.h> 10 #include <sched.h>
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 // function has completed. 73 // function has completed.
74 setenv(kSandboxDebuggingEnv, "t", 0); 74 setenv(kSandboxDebuggingEnv, "t", 0);
75 Die::SuppressInfoMessages(true); 75 Die::SuppressInfoMessages(true);
76 } 76 }
77 77
78 // This test should execute no matter whether we have kernel support. So, 78 // This test should execute no matter whether we have kernel support. So,
79 // we make it a TEST() instead of a BPF_TEST(). 79 // we make it a TEST() instead of a BPF_TEST().
80 TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupports)) { 80 TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupports)) {
81 // We check that we don't crash, but it's ok if the kernel doesn't 81 // We check that we don't crash, but it's ok if the kernel doesn't
82 // support it. 82 // support it.
83 const int seccomp_support = SandboxBPF::SupportsSeccompSandbox();
83 bool seccomp_bpf_supported = 84 bool seccomp_bpf_supported =
84 SandboxBPF::SupportsSeccompSandbox() == SandboxBPF::STATUS_AVAILABLE; 85 seccomp_support & SandboxBPF::SECCOMP_SINGLE_THREADED;
86 bool seccomp_bpf_tsync_supported =
87 seccomp_support & SandboxBPF::SECCOMP_MULTI_THREADED;
88
85 // We want to log whether or not seccomp BPF is actually supported 89 // We want to log whether or not seccomp BPF is actually supported
86 // since actual test coverage depends on it. 90 // since actual test coverage depends on it.
87 RecordProperty("SeccompBPFSupported", 91 std::cout << "Seccomp BPF supported (single thread): "
88 seccomp_bpf_supported ? "true." : "false.");
89 std::cout << "Seccomp BPF supported: "
90 << (seccomp_bpf_supported ? "true." : "false.") << "\n"; 92 << (seccomp_bpf_supported ? "true." : "false.") << "\n";
91 RecordProperty("PointerSize", sizeof(void*)); 93 std::cout << "Seccomp BPF supported (multi thread): "
94 << (seccomp_bpf_tsync_supported ? "true." : "false.") << "\n";
92 std::cout << "Pointer size: " << sizeof(void*) << "\n"; 95 std::cout << "Pointer size: " << sizeof(void*) << "\n";
93 } 96 }
94 97
95 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupportsTwice)) { 98 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupportsTwice)) {
96 SandboxBPF::SupportsSeccompSandbox(); 99 SandboxBPF::SupportsSeccompSandbox();
97 SandboxBPF::SupportsSeccompSandbox(); 100 SandboxBPF::SupportsSeccompSandbox();
98 } 101 }
99 102
100 // BPF_TEST does a lot of the boiler-plate code around setting up a 103 // BPF_TEST does a lot of the boiler-plate code around setting up a
101 // policy and optional passing data between the caller, the policy and 104 // policy and optional passing data between the caller, the policy and
(...skipping 22 matching lines...) Expand all
124 return Allow(); 127 return Allow();
125 } 128 }
126 129
127 private: 130 private:
128 int* counter_ptr_; 131 int* counter_ptr_;
129 132
130 DISALLOW_COPY_AND_ASSIGN(VerboseAPITestingPolicy); 133 DISALLOW_COPY_AND_ASSIGN(VerboseAPITestingPolicy);
131 }; 134 };
132 135
133 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) { 136 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) {
134 if (SandboxBPF::SupportsSeccompSandbox() == 137 if (SandboxBPF::SupportsSeccompSandbox() &
135 sandbox::SandboxBPF::STATUS_AVAILABLE) { 138 SandboxBPF::SECCOMP_SINGLE_THREADED) {
136 static int counter = 0; 139 static int counter = 0;
137 140
138 SandboxBPF sandbox; 141 SandboxBPF sandbox;
139 sandbox.SetSandboxPolicy(new VerboseAPITestingPolicy(&counter)); 142 sandbox.SetSandboxPolicy(new VerboseAPITestingPolicy(&counter));
140 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); 143 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::SECCOMP_SINGLE_THREADED));
141 144
142 BPF_ASSERT_EQ(0, counter); 145 BPF_ASSERT_EQ(0, counter);
143 BPF_ASSERT_EQ(0, syscall(__NR_uname, 0)); 146 BPF_ASSERT_EQ(0, syscall(__NR_uname, 0));
144 BPF_ASSERT_EQ(1, counter); 147 BPF_ASSERT_EQ(1, counter);
145 BPF_ASSERT_EQ(1, syscall(__NR_uname, 0)); 148 BPF_ASSERT_EQ(1, syscall(__NR_uname, 0));
146 BPF_ASSERT_EQ(2, counter); 149 BPF_ASSERT_EQ(2, counter);
147 } 150 }
148 } 151 }
149 152
150 // A simple blacklist test 153 // A simple blacklist test
(...skipping 21 matching lines...) Expand all
172 } 175 }
173 176
174 private: 177 private:
175 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); 178 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy);
176 }; 179 };
177 180
178 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { 181 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) {
179 BlacklistNanosleepPolicy::AssertNanosleepFails(); 182 BlacklistNanosleepPolicy::AssertNanosleepFails();
180 } 183 }
181 184
185 BPF_TEST_C(SandboxBPF, UseVsyscall, BlacklistNanosleepPolicy) {
186 time_t current_time;
187 // time() is implemented as a vsyscall. With an older glibc, with
188 // vsyscall=emulate and some versions of the seccomp BPF patch
189 // we may get SIGKILL-ed. Detect this!
190 BPF_ASSERT_NE(static_cast<time_t>(-1), time(&current_time));
191 }
192
182 // Now do a simple whitelist test 193 // Now do a simple whitelist test
183 194
184 class WhitelistGetpidPolicy : public Policy { 195 class WhitelistGetpidPolicy : public Policy {
185 public: 196 public:
186 WhitelistGetpidPolicy() {} 197 WhitelistGetpidPolicy() {}
187 ~WhitelistGetpidPolicy() override {} 198 ~WhitelistGetpidPolicy() override {}
188 199
189 ResultExpr EvaluateSyscall(int sysno) const override { 200 ResultExpr EvaluateSyscall(int sysno) const override {
190 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); 201 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno));
191 switch (sysno) { 202 switch (sysno) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); 402 BPF_ASSERT(syscall(__NR_getppid, 0) > 0);
392 BPF_ASSERT(errno == 0); 403 BPF_ASSERT(errno == 0);
393 404
394 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); 405 BPF_ASSERT(syscall(__NR_getppid, 1) == -1);
395 BPF_ASSERT(errno == EPERM); 406 BPF_ASSERT(errno == EPERM);
396 407
397 // Stack a second sandbox with its own policy. Verify that we can further 408 // Stack a second sandbox with its own policy. Verify that we can further
398 // restrict filters, but we cannot relax existing filters. 409 // restrict filters, but we cannot relax existing filters.
399 SandboxBPF sandbox; 410 SandboxBPF sandbox;
400 sandbox.SetSandboxPolicy(new StackingPolicyPartTwo()); 411 sandbox.SetSandboxPolicy(new StackingPolicyPartTwo());
401 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); 412 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::SECCOMP_SINGLE_THREADED));
402 413
403 errno = 0; 414 errno = 0;
404 BPF_ASSERT(syscall(__NR_getppid, 0) == -1); 415 BPF_ASSERT(syscall(__NR_getppid, 0) == -1);
405 BPF_ASSERT(errno == EINVAL); 416 BPF_ASSERT(errno == EINVAL);
406 417
407 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); 418 BPF_ASSERT(syscall(__NR_getppid, 1) == -1);
408 BPF_ASSERT(errno == EPERM); 419 BPF_ASSERT(errno == EPERM);
409 } 420 }
410 421
411 // A more complex, but synthetic policy. This tests the correctness of the BPF 422 // A more complex, but synthetic policy. This tests the correctness of the BPF
(...skipping 1650 matching lines...) Expand 10 before | Expand all | Expand 10 after
2062 2073
2063 ResultExpr EvaluateSyscall(int system_call_number) const override { 2074 ResultExpr EvaluateSyscall(int system_call_number) const override {
2064 return Trace(kTraceData); 2075 return Trace(kTraceData);
2065 } 2076 }
2066 2077
2067 private: 2078 private:
2068 DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy); 2079 DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy);
2069 }; 2080 };
2070 2081
2071 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { 2082 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) {
2072 if (SandboxBPF::SupportsSeccompSandbox() != 2083 if (SandboxBPF::SupportsSeccompSandbox() == SandboxBPF::SECCOMP_NONE) {
2073 sandbox::SandboxBPF::STATUS_AVAILABLE) {
2074 return; 2084 return;
2075 } 2085 }
2076 2086
2077 // This test is disabled on arm due to a kernel bug. 2087 // This test is disabled on arm due to a kernel bug.
2078 // See https://code.google.com/p/chromium/issues/detail?id=383977 2088 // See https://code.google.com/p/chromium/issues/detail?id=383977
2079 #if defined(__arm__) || defined(__aarch64__) 2089 #if defined(__arm__) || defined(__aarch64__)
2080 printf("This test is currently disabled on ARM32/64 due to a kernel bug."); 2090 printf("This test is currently disabled on ARM32/64 due to a kernel bug.");
2081 return; 2091 return;
2082 #endif 2092 #endif
2083 2093
2084 #if defined(__mips__) 2094 #if defined(__mips__)
2085 // TODO: Figure out how to support specificity of handling indirect syscalls 2095 // TODO: Figure out how to support specificity of handling indirect syscalls
2086 // in this test and enable it. 2096 // in this test and enable it.
2087 printf("This test is currently disabled on MIPS."); 2097 printf("This test is currently disabled on MIPS.");
2088 return; 2098 return;
2089 #endif 2099 #endif
2090 2100
2091 pid_t pid = fork(); 2101 pid_t pid = fork();
2092 BPF_ASSERT_NE(-1, pid); 2102 BPF_ASSERT_NE(-1, pid);
2093 if (pid == 0) { 2103 if (pid == 0) {
2094 pid_t my_pid = getpid(); 2104 pid_t my_pid = getpid();
2095 BPF_ASSERT_NE(-1, ptrace(PTRACE_TRACEME, -1, NULL, NULL)); 2105 BPF_ASSERT_NE(-1, ptrace(PTRACE_TRACEME, -1, NULL, NULL));
2096 BPF_ASSERT_EQ(0, raise(SIGSTOP)); 2106 BPF_ASSERT_EQ(0, raise(SIGSTOP));
2097 SandboxBPF sandbox; 2107 SandboxBPF sandbox;
2098 sandbox.SetSandboxPolicy(new TraceAllPolicy); 2108 sandbox.SetSandboxPolicy(new TraceAllPolicy);
2099 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); 2109 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::SECCOMP_SINGLE_THREADED));
2100 2110
2101 // getpid is allowed. 2111 // getpid is allowed.
2102 BPF_ASSERT_EQ(my_pid, sys_getpid()); 2112 BPF_ASSERT_EQ(my_pid, sys_getpid());
2103 2113
2104 // write to stdout is skipped and returns a fake value. 2114 // write to stdout is skipped and returns a fake value.
2105 BPF_ASSERT_EQ(kExpectedReturnValue, 2115 BPF_ASSERT_EQ(kExpectedReturnValue,
2106 syscall(__NR_write, STDOUT_FILENO, "A", 1)); 2116 syscall(__NR_write, STDOUT_FILENO, "A", 1));
2107 2117
2108 // kill is rewritten to exit(kExpectedReturnValue). 2118 // kill is rewritten to exit(kExpectedReturnValue).
2109 syscall(__NR_kill, my_pid, SIGKILL); 2119 syscall(__NR_kill, my_pid, SIGKILL);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 } 2270 }
2261 2271
2262 BPF_ASSERT(event->IsSignaled()); 2272 BPF_ASSERT(event->IsSignaled());
2263 2273
2264 BlacklistNanosleepPolicy::AssertNanosleepFails(); 2274 BlacklistNanosleepPolicy::AssertNanosleepFails();
2265 2275
2266 return NULL; 2276 return NULL;
2267 } 2277 }
2268 2278
2269 SANDBOX_TEST(SandboxBPF, Tsync) { 2279 SANDBOX_TEST(SandboxBPF, Tsync) {
2270 if (SandboxBPF::SupportsSeccompThreadFilterSynchronization() != 2280 if ((SandboxBPF::SupportsSeccompSandbox() &
2271 SandboxBPF::STATUS_AVAILABLE) { 2281 SandboxBPF::SECCOMP_MULTI_THREADED) == 0) {
2272 return; 2282 return;
2273 } 2283 }
2274 2284
2275 base::WaitableEvent event(true, false); 2285 base::WaitableEvent event(true, false);
2276 2286
2277 // Create a thread on which to invoke the blocked syscall. 2287 // Create a thread on which to invoke the blocked syscall.
2278 pthread_t thread; 2288 pthread_t thread;
2279 BPF_ASSERT_EQ( 2289 BPF_ASSERT_EQ(
2280 0, pthread_create(&thread, NULL, &TsyncApplyToTwoThreadsFunc, &event)); 2290 0, pthread_create(&thread, NULL, &TsyncApplyToTwoThreadsFunc, &event));
2281 2291
2282 // Test that nanoseelp success. 2292 // Test that nanoseelp success.
2283 const struct timespec ts = {0, 0}; 2293 const struct timespec ts = {0, 0};
2284 BPF_ASSERT_EQ(0, HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL))); 2294 BPF_ASSERT_EQ(0, HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL)));
2285 2295
2286 // Engage the sandbox. 2296 // Engage the sandbox.
2287 SandboxBPF sandbox; 2297 SandboxBPF sandbox;
2288 sandbox.SetSandboxPolicy(new BlacklistNanosleepPolicy()); 2298 sandbox.SetSandboxPolicy(new BlacklistNanosleepPolicy());
2289 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); 2299 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::SECCOMP_MULTI_THREADED));
2290 2300
2291 // This thread should have the filter applied as well. 2301 // This thread should have the filter applied as well.
2292 BlacklistNanosleepPolicy::AssertNanosleepFails(); 2302 BlacklistNanosleepPolicy::AssertNanosleepFails();
2293 2303
2294 // Signal the condition to invoke the system call. 2304 // Signal the condition to invoke the system call.
2295 event.Signal(); 2305 event.Signal();
2296 2306
2297 // Wait for the thread to finish. 2307 // Wait for the thread to finish.
2298 BPF_ASSERT_EQ(0, pthread_join(thread, NULL)); 2308 BPF_ASSERT_EQ(0, pthread_join(thread, NULL));
2299 } 2309 }
(...skipping 11 matching lines...) Expand all
2311 2321
2312 SANDBOX_DEATH_TEST( 2322 SANDBOX_DEATH_TEST(
2313 SandboxBPF, 2323 SandboxBPF,
2314 StartMultiThreadedAsSingleThreaded, 2324 StartMultiThreadedAsSingleThreaded,
2315 DEATH_MESSAGE("Cannot start sandbox; process is already multi-threaded")) { 2325 DEATH_MESSAGE("Cannot start sandbox; process is already multi-threaded")) {
2316 base::Thread thread("sandbox.linux.StartMultiThreadedAsSingleThreaded"); 2326 base::Thread thread("sandbox.linux.StartMultiThreadedAsSingleThreaded");
2317 BPF_ASSERT(thread.Start()); 2327 BPF_ASSERT(thread.Start());
2318 2328
2319 SandboxBPF sandbox; 2329 SandboxBPF sandbox;
2320 sandbox.SetSandboxPolicy(new AllowAllPolicy()); 2330 sandbox.SetSandboxPolicy(new AllowAllPolicy());
2321 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); 2331 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::SECCOMP_SINGLE_THREADED));
2322 } 2332 }
2323 2333
2324 // http://crbug.com/407357 2334 // http://crbug.com/407357
2325 #if !defined(THREAD_SANITIZER) 2335 #if !defined(THREAD_SANITIZER)
2326 SANDBOX_DEATH_TEST( 2336 SANDBOX_DEATH_TEST(
2327 SandboxBPF, 2337 SandboxBPF,
2328 StartSingleThreadedAsMultiThreaded, 2338 StartSingleThreadedAsMultiThreaded,
2329 DEATH_MESSAGE( 2339 DEATH_MESSAGE(
2330 "Cannot start sandbox; process may be single-threaded when " 2340 "Cannot start sandbox; process may be single-threaded when "
2331 "reported as not")) { 2341 "reported as not")) {
2332 SandboxBPF sandbox; 2342 SandboxBPF sandbox;
2333 sandbox.SetSandboxPolicy(new AllowAllPolicy()); 2343 sandbox.SetSandboxPolicy(new AllowAllPolicy());
2334 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); 2344 BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::SECCOMP_MULTI_THREADED));
2335 } 2345 }
2336 #endif // !defined(THREAD_SANITIZER) 2346 #endif // !defined(THREAD_SANITIZER)
2337 2347
2338 // A stub handler for the UnsafeTrap. Never called. 2348 // A stub handler for the UnsafeTrap. Never called.
2339 intptr_t NoOpHandler(const struct arch_seccomp_data& args, void*) { 2349 intptr_t NoOpHandler(const struct arch_seccomp_data& args, void*) {
2340 return -1; 2350 return -1;
2341 } 2351 }
2342 2352
2343 class UnsafeTrapWithCondPolicy : public Policy { 2353 class UnsafeTrapWithCondPolicy : public Policy {
2344 public: 2354 public:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2394 BPF_ASSERT_EQ(ENOSYS, errno); 2404 BPF_ASSERT_EQ(ENOSYS, errno);
2395 2405
2396 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); 2406 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300));
2397 BPF_ASSERT_EQ(EPERM, errno); 2407 BPF_ASSERT_EQ(EPERM, errno);
2398 } 2408 }
2399 2409
2400 } // namespace 2410 } // namespace
2401 2411
2402 } // namespace bpf_dsl 2412 } // namespace bpf_dsl
2403 } // namespace sandbox 2413 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698