| 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 "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 23 matching lines...) Expand all Loading... |
| 34 #include "build/build_config.h" | 34 #include "build/build_config.h" |
| 35 #include "sandbox/linux/bpf_dsl/policy.h" | 35 #include "sandbox/linux/bpf_dsl/policy.h" |
| 36 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" | 36 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
| 37 #include "sandbox/linux/seccomp-bpf/die.h" | 37 #include "sandbox/linux/seccomp-bpf/die.h" |
| 38 #include "sandbox/linux/seccomp-bpf/errorcode.h" | 38 #include "sandbox/linux/seccomp-bpf/errorcode.h" |
| 39 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" | 39 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" |
| 40 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 40 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
| 41 #include "sandbox/linux/seccomp-bpf/syscall.h" | 41 #include "sandbox/linux/seccomp-bpf/syscall.h" |
| 42 #include "sandbox/linux/seccomp-bpf/trap.h" | 42 #include "sandbox/linux/seccomp-bpf/trap.h" |
| 43 #include "sandbox/linux/services/linux_syscalls.h" | 43 #include "sandbox/linux/services/linux_syscalls.h" |
| 44 #include "sandbox/linux/services/syscall_wrappers.h" |
| 44 #include "sandbox/linux/syscall_broker/broker_process.h" | 45 #include "sandbox/linux/syscall_broker/broker_process.h" |
| 45 #include "sandbox/linux/tests/scoped_temporary_file.h" | 46 #include "sandbox/linux/tests/scoped_temporary_file.h" |
| 46 #include "sandbox/linux/tests/unit_tests.h" | 47 #include "sandbox/linux/tests/unit_tests.h" |
| 47 #include "testing/gtest/include/gtest/gtest.h" | 48 #include "testing/gtest/include/gtest/gtest.h" |
| 48 | 49 |
| 49 // Workaround for Android's prctl.h file. | 50 // Workaround for Android's prctl.h file. |
| 50 #ifndef PR_GET_ENDIAN | 51 #ifndef PR_GET_ENDIAN |
| 51 #define PR_GET_ENDIAN 19 | 52 #define PR_GET_ENDIAN 19 |
| 52 #endif | 53 #endif |
| 53 #ifndef PR_CAPBSET_READ | 54 #ifndef PR_CAPBSET_READ |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 } | 197 } |
| 197 } | 198 } |
| 198 | 199 |
| 199 private: | 200 private: |
| 200 DISALLOW_COPY_AND_ASSIGN(WhitelistGetpidPolicy); | 201 DISALLOW_COPY_AND_ASSIGN(WhitelistGetpidPolicy); |
| 201 }; | 202 }; |
| 202 | 203 |
| 203 BPF_TEST_C(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { | 204 BPF_TEST_C(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { |
| 204 // getpid() should be allowed | 205 // getpid() should be allowed |
| 205 errno = 0; | 206 errno = 0; |
| 206 BPF_ASSERT(syscall(__NR_getpid) > 0); | 207 BPF_ASSERT(sys_getpid() > 0); |
| 207 BPF_ASSERT(errno == 0); | 208 BPF_ASSERT(errno == 0); |
| 208 | 209 |
| 209 // getpgid() should be denied | 210 // getpgid() should be denied |
| 210 BPF_ASSERT(getpgid(0) == -1); | 211 BPF_ASSERT(getpgid(0) == -1); |
| 211 BPF_ASSERT(errno == ENOMEM); | 212 BPF_ASSERT(errno == ENOMEM); |
| 212 } | 213 } |
| 213 | 214 |
| 214 // A simple blacklist policy, with a SIGSYS handler | 215 // A simple blacklist policy, with a SIGSYS handler |
| 215 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { | 216 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { |
| 216 // We also check that the auxiliary data is correct | 217 // We also check that the auxiliary data is correct |
| (...skipping 22 matching lines...) Expand all Loading... |
| 239 | 240 |
| 240 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepTrapPolicy); | 241 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepTrapPolicy); |
| 241 }; | 242 }; |
| 242 | 243 |
| 243 BPF_TEST(SandboxBPF, | 244 BPF_TEST(SandboxBPF, |
| 244 BasicBlacklistWithSigsys, | 245 BasicBlacklistWithSigsys, |
| 245 BlacklistNanosleepTrapPolicy, | 246 BlacklistNanosleepTrapPolicy, |
| 246 int /* (*BPF_AUX) */) { | 247 int /* (*BPF_AUX) */) { |
| 247 // getpid() should work properly | 248 // getpid() should work properly |
| 248 errno = 0; | 249 errno = 0; |
| 249 BPF_ASSERT(syscall(__NR_getpid) > 0); | 250 BPF_ASSERT(sys_getpid() > 0); |
| 250 BPF_ASSERT(errno == 0); | 251 BPF_ASSERT(errno == 0); |
| 251 | 252 |
| 252 // Our Auxiliary Data, should be reset by the signal handler | 253 // Our Auxiliary Data, should be reset by the signal handler |
| 253 *BPF_AUX = -1; | 254 *BPF_AUX = -1; |
| 254 const struct timespec ts = {0, 0}; | 255 const struct timespec ts = {0, 0}; |
| 255 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 256 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| 256 BPF_ASSERT(errno == ENOMEM); | 257 BPF_ASSERT(errno == ENOMEM); |
| 257 | 258 |
| 258 // We expect the signal handler to modify AuxData | 259 // We expect the signal handler to modify AuxData |
| 259 BPF_ASSERT(*BPF_AUX == kExpectedReturnValue); | 260 BPF_ASSERT(*BPF_AUX == kExpectedReturnValue); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 } | 506 } |
| 506 } | 507 } |
| 507 #endif // defined(__arm__) | 508 #endif // defined(__arm__) |
| 508 | 509 |
| 509 intptr_t CountSyscalls(const struct arch_seccomp_data& args, void* aux) { | 510 intptr_t CountSyscalls(const struct arch_seccomp_data& args, void* aux) { |
| 510 // Count all invocations of our callback function. | 511 // Count all invocations of our callback function. |
| 511 ++*reinterpret_cast<int*>(aux); | 512 ++*reinterpret_cast<int*>(aux); |
| 512 | 513 |
| 513 // Verify that within the callback function all filtering is temporarily | 514 // Verify that within the callback function all filtering is temporarily |
| 514 // disabled. | 515 // disabled. |
| 515 BPF_ASSERT(syscall(__NR_getpid) > 1); | 516 BPF_ASSERT(sys_getpid() > 1); |
| 516 | 517 |
| 517 // Verify that we can now call the underlying system call without causing | 518 // Verify that we can now call the underlying system call without causing |
| 518 // infinite recursion. | 519 // infinite recursion. |
| 519 return SandboxBPF::ForwardSyscall(args); | 520 return SandboxBPF::ForwardSyscall(args); |
| 520 } | 521 } |
| 521 | 522 |
| 522 class GreyListedPolicy : public Policy { | 523 class GreyListedPolicy : public Policy { |
| 523 public: | 524 public: |
| 524 explicit GreyListedPolicy(int* aux) : aux_(aux) { | 525 explicit GreyListedPolicy(int* aux) : aux_(aux) { |
| 525 // Set the global environment for unsafe traps once. | 526 // Set the global environment for unsafe traps once. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 542 } | 543 } |
| 543 } | 544 } |
| 544 | 545 |
| 545 private: | 546 private: |
| 546 int* aux_; | 547 int* aux_; |
| 547 | 548 |
| 548 DISALLOW_COPY_AND_ASSIGN(GreyListedPolicy); | 549 DISALLOW_COPY_AND_ASSIGN(GreyListedPolicy); |
| 549 }; | 550 }; |
| 550 | 551 |
| 551 BPF_TEST(SandboxBPF, GreyListedPolicy, GreyListedPolicy, int /* (*BPF_AUX) */) { | 552 BPF_TEST(SandboxBPF, GreyListedPolicy, GreyListedPolicy, int /* (*BPF_AUX) */) { |
| 552 BPF_ASSERT(syscall(__NR_getpid) == -1); | 553 BPF_ASSERT(sys_getpid() == -1); |
| 553 BPF_ASSERT(errno == EPERM); | 554 BPF_ASSERT(errno == EPERM); |
| 554 BPF_ASSERT(*BPF_AUX == 0); | 555 BPF_ASSERT(*BPF_AUX == 0); |
| 555 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); | 556 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); |
| 556 BPF_ASSERT(*BPF_AUX == 2); | 557 BPF_ASSERT(*BPF_AUX == 2); |
| 557 char name[17] = {}; | 558 char name[17] = {}; |
| 558 BPF_ASSERT(!syscall(__NR_prctl, | 559 BPF_ASSERT(!syscall(__NR_prctl, |
| 559 PR_GET_NAME, | 560 PR_GET_NAME, |
| 560 name, | 561 name, |
| 561 (void*)NULL, | 562 (void*)NULL, |
| 562 (void*)NULL, | 563 (void*)NULL, |
| (...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2091 BPF_ASSERT_NE(-1, pid); | 2092 BPF_ASSERT_NE(-1, pid); |
| 2092 if (pid == 0) { | 2093 if (pid == 0) { |
| 2093 pid_t my_pid = getpid(); | 2094 pid_t my_pid = getpid(); |
| 2094 BPF_ASSERT_NE(-1, ptrace(PTRACE_TRACEME, -1, NULL, NULL)); | 2095 BPF_ASSERT_NE(-1, ptrace(PTRACE_TRACEME, -1, NULL, NULL)); |
| 2095 BPF_ASSERT_EQ(0, raise(SIGSTOP)); | 2096 BPF_ASSERT_EQ(0, raise(SIGSTOP)); |
| 2096 SandboxBPF sandbox; | 2097 SandboxBPF sandbox; |
| 2097 sandbox.SetSandboxPolicy(new TraceAllPolicy); | 2098 sandbox.SetSandboxPolicy(new TraceAllPolicy); |
| 2098 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); | 2099 BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |
| 2099 | 2100 |
| 2100 // getpid is allowed. | 2101 // getpid is allowed. |
| 2101 BPF_ASSERT_EQ(my_pid, syscall(__NR_getpid)); | 2102 BPF_ASSERT_EQ(my_pid, sys_getpid()); |
| 2102 | 2103 |
| 2103 // write to stdout is skipped and returns a fake value. | 2104 // write to stdout is skipped and returns a fake value. |
| 2104 BPF_ASSERT_EQ(kExpectedReturnValue, | 2105 BPF_ASSERT_EQ(kExpectedReturnValue, |
| 2105 syscall(__NR_write, STDOUT_FILENO, "A", 1)); | 2106 syscall(__NR_write, STDOUT_FILENO, "A", 1)); |
| 2106 | 2107 |
| 2107 // kill is rewritten to exit(kExpectedReturnValue). | 2108 // kill is rewritten to exit(kExpectedReturnValue). |
| 2108 syscall(__NR_kill, my_pid, SIGKILL); | 2109 syscall(__NR_kill, my_pid, SIGKILL); |
| 2109 | 2110 |
| 2110 // Should not be reached. | 2111 // Should not be reached. |
| 2111 BPF_ASSERT(false); | 2112 BPF_ASSERT(false); |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2393 BPF_ASSERT_EQ(ENOSYS, errno); | 2394 BPF_ASSERT_EQ(ENOSYS, errno); |
| 2394 | 2395 |
| 2395 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); | 2396 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); |
| 2396 BPF_ASSERT_EQ(EPERM, errno); | 2397 BPF_ASSERT_EQ(EPERM, errno); |
| 2397 } | 2398 } |
| 2398 | 2399 |
| 2399 } // namespace | 2400 } // namespace |
| 2400 | 2401 |
| 2401 } // namespace bpf_dsl | 2402 } // namespace bpf_dsl |
| 2402 } // namespace sandbox | 2403 } // namespace sandbox |
| OLD | NEW |