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 <sys/prctl.h> | 8 #include <sys/prctl.h> |
9 #include <sys/syscall.h> | 9 #include <sys/syscall.h> |
10 #include <sys/time.h> | 10 #include <sys/time.h> |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 // and it helps us accidentally forgetting any of the crucial steps in | 77 // and it helps us accidentally forgetting any of the crucial steps in |
78 // setting up the sandbox. But it wouldn't hurt to have at least one test | 78 // setting up the sandbox. But it wouldn't hurt to have at least one test |
79 // that explicitly walks through all these steps. | 79 // that explicitly walks through all these steps. |
80 | 80 |
81 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void* aux) { | 81 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void* aux) { |
82 BPF_ASSERT(aux); | 82 BPF_ASSERT(aux); |
83 pid_t* pid_ptr = static_cast<pid_t*>(aux); | 83 pid_t* pid_ptr = static_cast<pid_t*>(aux); |
84 return (*pid_ptr)++; | 84 return (*pid_ptr)++; |
85 } | 85 } |
86 | 86 |
87 ErrorCode VerboseAPITestingPolicy(SandboxBPF* sandbox, int sysno, void* aux) { | 87 class VerboseAPITestingPolicy : public SandboxBPFPolicy { |
88 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 88 public: |
89 return ErrorCode(ENOSYS); | 89 VerboseAPITestingPolicy(pid_t* pid_ptr) : pid_ptr_(pid_ptr) {} |
90 } else if (sysno == __NR_getpid) { | 90 |
91 return sandbox->Trap(FakeGetPid, aux); | 91 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
92 } else { | 92 int sysno) const OVERRIDE { |
| 93 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 94 if (sysno == __NR_getpid) { |
| 95 return sandbox->Trap(FakeGetPid, pid_ptr_); |
| 96 } |
93 return ErrorCode(ErrorCode::ERR_ALLOWED); | 97 return ErrorCode(ErrorCode::ERR_ALLOWED); |
94 } | 98 } |
95 } | 99 |
| 100 private: |
| 101 pid_t* pid_ptr_; |
| 102 }; |
96 | 103 |
97 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) { | 104 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) { |
98 if (SandboxBPF::SupportsSeccompSandbox(-1) == | 105 if (SandboxBPF::SupportsSeccompSandbox(-1) == |
99 sandbox::SandboxBPF::STATUS_AVAILABLE) { | 106 sandbox::SandboxBPF::STATUS_AVAILABLE) { |
100 pid_t test_var = 0; | 107 pid_t pid; |
| 108 |
101 SandboxBPF sandbox; | 109 SandboxBPF sandbox; |
102 sandbox.SetSandboxPolicyDeprecated(VerboseAPITestingPolicy, &test_var); | 110 sandbox.SetSandboxPolicy(new VerboseAPITestingPolicy(&pid)); |
103 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); | 111 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |
104 | 112 |
105 BPF_ASSERT(test_var == 0); | 113 BPF_ASSERT_EQ(0, pid); |
106 BPF_ASSERT(syscall(__NR_getpid) == 0); | 114 BPF_ASSERT_EQ(0, syscall(__NR_getpid)); |
107 BPF_ASSERT(test_var == 1); | 115 BPF_ASSERT_EQ(1, pid); |
108 BPF_ASSERT(syscall(__NR_getpid) == 1); | 116 BPF_ASSERT_EQ(1, syscall(__NR_getpid)); |
109 BPF_ASSERT(test_var == 2); | 117 BPF_ASSERT_EQ(2, pid); |
110 | 118 |
111 // N.B.: Any future call to getpid() would corrupt the stack. | 119 // N.B.: Any future call to getpid() would corrupt the stack. |
112 // This is OK. The SANDBOX_TEST() macro is guaranteed to | 120 // This is OK. The SANDBOX_TEST() macro is guaranteed to |
113 // only ever call _exit() after the test completes. | 121 // only ever call _exit() after the test completes. |
114 } | 122 } |
115 } | 123 } |
116 | 124 |
117 // A simple blacklist test | 125 // A simple blacklist test |
118 | 126 |
119 ErrorCode BlacklistNanosleepPolicy(SandboxBPF*, int sysno, void* aux) { | 127 ErrorCode BlacklistNanosleepPolicy(SandboxBPF*, int sysno, void* aux) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 | 285 |
278 // Finally, test an errno in between the minimum and maximum. | 286 // Finally, test an errno in between the minimum and maximum. |
279 errno = 0; | 287 errno = 0; |
280 struct utsname uts_buf; | 288 struct utsname uts_buf; |
281 BPF_ASSERT(uname(&uts_buf) == -1); | 289 BPF_ASSERT(uname(&uts_buf) == -1); |
282 BPF_ASSERT(errno == 42); | 290 BPF_ASSERT(errno == 42); |
283 } | 291 } |
284 | 292 |
285 // Testing the stacking of two sandboxes | 293 // Testing the stacking of two sandboxes |
286 | 294 |
287 ErrorCode StackingPolicyPartOne(SandboxBPF* sandbox, int sysno, void*) { | 295 class StackingPolicyPartOne : public SandboxBPFPolicy { |
288 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 296 public: |
289 return ErrorCode(ENOSYS); | 297 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 298 int sysno) const OVERRIDE { |
| 299 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 300 switch (sysno) { |
| 301 case __NR_getppid: |
| 302 return sandbox->Cond(0, |
| 303 ErrorCode::TP_32BIT, |
| 304 ErrorCode::OP_EQUAL, |
| 305 0, |
| 306 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 307 ErrorCode(EPERM)); |
| 308 default: |
| 309 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 310 } |
290 } | 311 } |
| 312 }; |
291 | 313 |
292 switch (sysno) { | 314 class StackingPolicyPartTwo : public SandboxBPFPolicy { |
293 case __NR_getppid: | 315 public: |
294 return sandbox->Cond(0, | 316 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
295 ErrorCode::TP_32BIT, | 317 int sysno) const OVERRIDE { |
296 ErrorCode::OP_EQUAL, | 318 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
297 0, | 319 switch (sysno) { |
298 ErrorCode(ErrorCode::ERR_ALLOWED), | 320 case __NR_getppid: |
299 ErrorCode(EPERM)); | 321 return sandbox->Cond(0, |
300 default: | 322 ErrorCode::TP_32BIT, |
301 return ErrorCode(ErrorCode::ERR_ALLOWED); | 323 ErrorCode::OP_EQUAL, |
| 324 0, |
| 325 ErrorCode(EINVAL), |
| 326 ErrorCode(ErrorCode::ERR_ALLOWED)); |
| 327 default: |
| 328 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 329 } |
302 } | 330 } |
303 } | 331 }; |
304 | 332 |
305 ErrorCode StackingPolicyPartTwo(SandboxBPF* sandbox, int sysno, void*) { | 333 BPF_TEST_C(SandboxBPF, StackingPolicy, StackingPolicyPartOne) { |
306 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | |
307 return ErrorCode(ENOSYS); | |
308 } | |
309 | |
310 switch (sysno) { | |
311 case __NR_getppid: | |
312 return sandbox->Cond(0, | |
313 ErrorCode::TP_32BIT, | |
314 ErrorCode::OP_EQUAL, | |
315 0, | |
316 ErrorCode(EINVAL), | |
317 ErrorCode(ErrorCode::ERR_ALLOWED)); | |
318 default: | |
319 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
320 } | |
321 } | |
322 | |
323 BPF_TEST(SandboxBPF, StackingPolicy, StackingPolicyPartOne) { | |
324 errno = 0; | 334 errno = 0; |
325 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); | 335 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); |
326 BPF_ASSERT(errno == 0); | 336 BPF_ASSERT(errno == 0); |
327 | 337 |
328 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); | 338 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); |
329 BPF_ASSERT(errno == EPERM); | 339 BPF_ASSERT(errno == EPERM); |
330 | 340 |
331 // Stack a second sandbox with its own policy. Verify that we can further | 341 // Stack a second sandbox with its own policy. Verify that we can further |
332 // restrict filters, but we cannot relax existing filters. | 342 // restrict filters, but we cannot relax existing filters. |
333 SandboxBPF sandbox; | 343 SandboxBPF sandbox; |
334 sandbox.SetSandboxPolicyDeprecated(StackingPolicyPartTwo, NULL); | 344 sandbox.SetSandboxPolicy(new StackingPolicyPartTwo()); |
335 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); | 345 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |
336 | 346 |
337 errno = 0; | 347 errno = 0; |
338 BPF_ASSERT(syscall(__NR_getppid, 0) == -1); | 348 BPF_ASSERT(syscall(__NR_getppid, 0) == -1); |
339 BPF_ASSERT(errno == EINVAL); | 349 BPF_ASSERT(errno == EINVAL); |
340 | 350 |
341 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); | 351 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); |
342 BPF_ASSERT(errno == EPERM); | 352 BPF_ASSERT(errno == EPERM); |
343 } | 353 } |
344 | 354 |
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1802 &pid) == -EPERM); | 1812 &pid) == -EPERM); |
1803 } | 1813 } |
1804 | 1814 |
1805 BPF_TEST(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); } | 1815 BPF_TEST(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); } |
1806 | 1816 |
1807 BPF_TEST(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); } | 1817 BPF_TEST(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); } |
1808 | 1818 |
1809 } // namespace | 1819 } // namespace |
1810 | 1820 |
1811 } // namespace sandbox | 1821 } // namespace sandbox |
OLD | NEW |