| 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 24 matching lines...) Expand all  Loading... | 
| 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/services/syscall_wrappers.h" | 
|  | 45 #include "sandbox/linux/syscall_broker/broker_file_permission.h" | 
| 45 #include "sandbox/linux/syscall_broker/broker_process.h" | 46 #include "sandbox/linux/syscall_broker/broker_process.h" | 
| 46 #include "sandbox/linux/tests/scoped_temporary_file.h" | 47 #include "sandbox/linux/tests/scoped_temporary_file.h" | 
| 47 #include "sandbox/linux/tests/unit_tests.h" | 48 #include "sandbox/linux/tests/unit_tests.h" | 
| 48 #include "testing/gtest/include/gtest/gtest.h" | 49 #include "testing/gtest/include/gtest/gtest.h" | 
| 49 | 50 | 
| 50 // Workaround for Android's prctl.h file. | 51 // Workaround for Android's prctl.h file. | 
| 51 #ifndef PR_GET_ENDIAN | 52 #ifndef PR_GET_ENDIAN | 
| 52 #define PR_GET_ENDIAN 19 | 53 #define PR_GET_ENDIAN 19 | 
| 53 #endif | 54 #endif | 
| 54 #ifndef PR_CAPBSET_READ | 55 #ifndef PR_CAPBSET_READ | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 68 void EnableUnsafeTraps() { | 69 void EnableUnsafeTraps() { | 
| 69   // The use of UnsafeTrap() causes us to print a warning message. This is | 70   // The use of UnsafeTrap() causes us to print a warning message. This is | 
| 70   // generally desirable, but it results in the unittest failing, as it doesn't | 71   // generally desirable, but it results in the unittest failing, as it doesn't | 
| 71   // expect any messages on "stderr". So, temporarily disable messages. The | 72   // expect any messages on "stderr". So, temporarily disable messages. The | 
| 72   // BPF_TEST() is guaranteed to turn messages back on, after the policy | 73   // BPF_TEST() is guaranteed to turn messages back on, after the policy | 
| 73   // function has completed. | 74   // function has completed. | 
| 74   setenv(kSandboxDebuggingEnv, "t", 0); | 75   setenv(kSandboxDebuggingEnv, "t", 0); | 
| 75   Die::SuppressInfoMessages(true); | 76   Die::SuppressInfoMessages(true); | 
| 76 } | 77 } | 
| 77 | 78 | 
| 78 // This test should execute no matter whether we have kernel support. So, |  | 
| 79 // we make it a TEST() instead of a BPF_TEST(). |  | 
| 80 TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupports)) { |  | 
| 81   // We check that we don't crash, but it's ok if the kernel doesn't |  | 
| 82   // support it. |  | 
| 83   bool seccomp_bpf_supported = |  | 
| 84       SandboxBPF::SupportsSeccompSandbox(-1) == SandboxBPF::STATUS_AVAILABLE; |  | 
| 85   // We want to log whether or not seccomp BPF is actually supported |  | 
| 86   // since actual test coverage depends on it. |  | 
| 87   RecordProperty("SeccompBPFSupported", |  | 
| 88                  seccomp_bpf_supported ? "true." : "false."); |  | 
| 89   std::cout << "Seccomp BPF supported: " |  | 
| 90             << (seccomp_bpf_supported ? "true." : "false.") << "\n"; |  | 
| 91   RecordProperty("PointerSize", sizeof(void*)); |  | 
| 92   std::cout << "Pointer size: " << sizeof(void*) << "\n"; |  | 
| 93 } |  | 
| 94 |  | 
| 95 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupportsTwice)) { |  | 
| 96   SandboxBPF::SupportsSeccompSandbox(-1); |  | 
| 97   SandboxBPF::SupportsSeccompSandbox(-1); |  | 
| 98 } |  | 
| 99 |  | 
| 100 // BPF_TEST does a lot of the boiler-plate code around setting up a | 79 // 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 | 80 // policy and optional passing data between the caller, the policy and | 
| 102 // any Trap() handlers. This is great for writing short and concise tests, | 81 // any Trap() handlers. This is great for writing short and concise tests, | 
| 103 // and it helps us accidentally forgetting any of the crucial steps in | 82 // and it helps us accidentally forgetting any of the crucial steps in | 
| 104 // setting up the sandbox. But it wouldn't hurt to have at least one test | 83 // setting up the sandbox. But it wouldn't hurt to have at least one test | 
| 105 // that explicitly walks through all these steps. | 84 // that explicitly walks through all these steps. | 
| 106 | 85 | 
| 107 intptr_t IncreaseCounter(const struct arch_seccomp_data& args, void* aux) { | 86 intptr_t IncreaseCounter(const struct arch_seccomp_data& args, void* aux) { | 
| 108   BPF_ASSERT(aux); | 87   BPF_ASSERT(aux); | 
| 109   int* counter = static_cast<int*>(aux); | 88   int* counter = static_cast<int*>(aux); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 124     return Allow(); | 103     return Allow(); | 
| 125   } | 104   } | 
| 126 | 105 | 
| 127  private: | 106  private: | 
| 128   int* counter_ptr_; | 107   int* counter_ptr_; | 
| 129 | 108 | 
| 130   DISALLOW_COPY_AND_ASSIGN(VerboseAPITestingPolicy); | 109   DISALLOW_COPY_AND_ASSIGN(VerboseAPITestingPolicy); | 
| 131 }; | 110 }; | 
| 132 | 111 | 
| 133 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) { | 112 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(VerboseAPITesting)) { | 
| 134   if (SandboxBPF::SupportsSeccompSandbox(-1) == | 113   if (SandboxBPF::SupportsSeccompSandbox( | 
| 135       sandbox::SandboxBPF::STATUS_AVAILABLE) { | 114           SandboxBPF::SeccompLevel::SINGLE_THREADED)) { | 
| 136     static int counter = 0; | 115     static int counter = 0; | 
| 137 | 116 | 
| 138     SandboxBPF sandbox; | 117     SandboxBPF sandbox(new VerboseAPITestingPolicy(&counter)); | 
| 139     sandbox.SetSandboxPolicy(new VerboseAPITestingPolicy(&counter)); | 118     BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::SeccompLevel::SINGLE_THREADED)); | 
| 140     BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |  | 
| 141 | 119 | 
| 142     BPF_ASSERT_EQ(0, counter); | 120     BPF_ASSERT_EQ(0, counter); | 
| 143     BPF_ASSERT_EQ(0, syscall(__NR_uname, 0)); | 121     BPF_ASSERT_EQ(0, syscall(__NR_uname, 0)); | 
| 144     BPF_ASSERT_EQ(1, counter); | 122     BPF_ASSERT_EQ(1, counter); | 
| 145     BPF_ASSERT_EQ(1, syscall(__NR_uname, 0)); | 123     BPF_ASSERT_EQ(1, syscall(__NR_uname, 0)); | 
| 146     BPF_ASSERT_EQ(2, counter); | 124     BPF_ASSERT_EQ(2, counter); | 
| 147   } | 125   } | 
| 148 } | 126 } | 
| 149 | 127 | 
| 150 // A simple blacklist test | 128 // A simple blacklist test | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 172   } | 150   } | 
| 173 | 151 | 
| 174  private: | 152  private: | 
| 175   DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); | 153   DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); | 
| 176 }; | 154 }; | 
| 177 | 155 | 
| 178 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | 156 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | 
| 179   BlacklistNanosleepPolicy::AssertNanosleepFails(); | 157   BlacklistNanosleepPolicy::AssertNanosleepFails(); | 
| 180 } | 158 } | 
| 181 | 159 | 
|  | 160 BPF_TEST_C(SandboxBPF, UseVsyscall, BlacklistNanosleepPolicy) { | 
|  | 161   time_t current_time; | 
|  | 162   // time() is implemented as a vsyscall. With an older glibc, with | 
|  | 163   // vsyscall=emulate and some versions of the seccomp BPF patch | 
|  | 164   // we may get SIGKILL-ed. Detect this! | 
|  | 165   BPF_ASSERT_NE(static_cast<time_t>(-1), time(¤t_time)); | 
|  | 166 } | 
|  | 167 | 
| 182 // Now do a simple whitelist test | 168 // Now do a simple whitelist test | 
| 183 | 169 | 
| 184 class WhitelistGetpidPolicy : public Policy { | 170 class WhitelistGetpidPolicy : public Policy { | 
| 185  public: | 171  public: | 
| 186   WhitelistGetpidPolicy() {} | 172   WhitelistGetpidPolicy() {} | 
| 187   ~WhitelistGetpidPolicy() override {} | 173   ~WhitelistGetpidPolicy() override {} | 
| 188 | 174 | 
| 189   ResultExpr EvaluateSyscall(int sysno) const override { | 175   ResultExpr EvaluateSyscall(int sysno) const override { | 
| 190     DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 176     DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 
| 191     switch (sysno) { | 177     switch (sysno) { | 
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 389 BPF_TEST_C(SandboxBPF, StackingPolicy, StackingPolicyPartOne) { | 375 BPF_TEST_C(SandboxBPF, StackingPolicy, StackingPolicyPartOne) { | 
| 390   errno = 0; | 376   errno = 0; | 
| 391   BPF_ASSERT(syscall(__NR_getppid, 0) > 0); | 377   BPF_ASSERT(syscall(__NR_getppid, 0) > 0); | 
| 392   BPF_ASSERT(errno == 0); | 378   BPF_ASSERT(errno == 0); | 
| 393 | 379 | 
| 394   BPF_ASSERT(syscall(__NR_getppid, 1) == -1); | 380   BPF_ASSERT(syscall(__NR_getppid, 1) == -1); | 
| 395   BPF_ASSERT(errno == EPERM); | 381   BPF_ASSERT(errno == EPERM); | 
| 396 | 382 | 
| 397   // Stack a second sandbox with its own policy. Verify that we can further | 383   // Stack a second sandbox with its own policy. Verify that we can further | 
| 398   // restrict filters, but we cannot relax existing filters. | 384   // restrict filters, but we cannot relax existing filters. | 
| 399   SandboxBPF sandbox; | 385   SandboxBPF sandbox(new StackingPolicyPartTwo()); | 
| 400   sandbox.SetSandboxPolicy(new StackingPolicyPartTwo()); | 386   BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::SeccompLevel::SINGLE_THREADED)); | 
| 401   BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |  | 
| 402 | 387 | 
| 403   errno = 0; | 388   errno = 0; | 
| 404   BPF_ASSERT(syscall(__NR_getppid, 0) == -1); | 389   BPF_ASSERT(syscall(__NR_getppid, 0) == -1); | 
| 405   BPF_ASSERT(errno == EINVAL); | 390   BPF_ASSERT(errno == EINVAL); | 
| 406 | 391 | 
| 407   BPF_ASSERT(syscall(__NR_getppid, 1) == -1); | 392   BPF_ASSERT(syscall(__NR_getppid, 1) == -1); | 
| 408   BPF_ASSERT(errno == EPERM); | 393   BPF_ASSERT(errno == EPERM); | 
| 409 } | 394 } | 
| 410 | 395 | 
| 411 // A more complex, but synthetic policy. This tests the correctness of the BPF | 396 // A more complex, but synthetic policy. This tests the correctness of the BPF | 
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 749 | 734 | 
| 750 bool NoOpCallback() { | 735 bool NoOpCallback() { | 
| 751   return true; | 736   return true; | 
| 752 } | 737 } | 
| 753 | 738 | 
| 754 // Test a trap handler that makes use of a broker process to open(). | 739 // Test a trap handler that makes use of a broker process to open(). | 
| 755 | 740 | 
| 756 class InitializedOpenBroker { | 741 class InitializedOpenBroker { | 
| 757  public: | 742  public: | 
| 758   InitializedOpenBroker() : initialized_(false) { | 743   InitializedOpenBroker() : initialized_(false) { | 
| 759     std::vector<std::string> allowed_files; | 744     std::vector<syscall_broker::BrokerFilePermission> permissions; | 
| 760     allowed_files.push_back("/proc/allowed"); | 745     permissions.push_back( | 
| 761     allowed_files.push_back("/proc/cpuinfo"); | 746         syscall_broker::BrokerFilePermission::ReadOnly("/proc/allowed")); | 
|  | 747     permissions.push_back( | 
|  | 748         syscall_broker::BrokerFilePermission::ReadOnly("/proc/cpuinfo")); | 
| 762 | 749 | 
| 763     broker_process_.reset(new syscall_broker::BrokerProcess( | 750     broker_process_.reset( | 
| 764         EPERM, allowed_files, std::vector<std::string>())); | 751         new syscall_broker::BrokerProcess(EPERM, permissions)); | 
| 765     BPF_ASSERT(broker_process() != NULL); | 752     BPF_ASSERT(broker_process() != NULL); | 
| 766     BPF_ASSERT(broker_process_->Init(base::Bind(&NoOpCallback))); | 753     BPF_ASSERT(broker_process_->Init(base::Bind(&NoOpCallback))); | 
| 767 | 754 | 
| 768     initialized_ = true; | 755     initialized_ = true; | 
| 769   } | 756   } | 
| 770   bool initialized() { return initialized_; } | 757   bool initialized() { return initialized_; } | 
| 771   class syscall_broker::BrokerProcess* broker_process() { | 758   class syscall_broker::BrokerProcess* broker_process() { | 
| 772     return broker_process_.get(); | 759     return broker_process_.get(); | 
| 773   } | 760   } | 
| 774 | 761 | 
| (...skipping 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2062 | 2049 | 
| 2063   ResultExpr EvaluateSyscall(int system_call_number) const override { | 2050   ResultExpr EvaluateSyscall(int system_call_number) const override { | 
| 2064     return Trace(kTraceData); | 2051     return Trace(kTraceData); | 
| 2065   } | 2052   } | 
| 2066 | 2053 | 
| 2067  private: | 2054  private: | 
| 2068   DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy); | 2055   DISALLOW_COPY_AND_ASSIGN(TraceAllPolicy); | 
| 2069 }; | 2056 }; | 
| 2070 | 2057 | 
| 2071 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { | 2058 SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(SeccompRetTrace)) { | 
| 2072   if (SandboxBPF::SupportsSeccompSandbox(-1) != | 2059   if (!SandboxBPF::SupportsSeccompSandbox( | 
| 2073       sandbox::SandboxBPF::STATUS_AVAILABLE) { | 2060           SandboxBPF::SeccompLevel::SINGLE_THREADED)) { | 
| 2074     return; | 2061     return; | 
| 2075   } | 2062   } | 
| 2076 | 2063 | 
| 2077 // This test is disabled on arm due to a kernel bug. | 2064 // This test is disabled on arm due to a kernel bug. | 
| 2078 // See https://code.google.com/p/chromium/issues/detail?id=383977 | 2065 // See https://code.google.com/p/chromium/issues/detail?id=383977 | 
| 2079 #if defined(__arm__) || defined(__aarch64__) | 2066 #if defined(__arm__) || defined(__aarch64__) | 
| 2080   printf("This test is currently disabled on ARM32/64 due to a kernel bug."); | 2067   printf("This test is currently disabled on ARM32/64 due to a kernel bug."); | 
| 2081   return; | 2068   return; | 
| 2082 #endif | 2069 #endif | 
| 2083 | 2070 | 
| 2084 #if defined(__mips__) | 2071 #if defined(__mips__) | 
| 2085   // TODO: Figure out how to support specificity of handling indirect syscalls | 2072   // TODO: Figure out how to support specificity of handling indirect syscalls | 
| 2086   //        in this test and enable it. | 2073   //        in this test and enable it. | 
| 2087   printf("This test is currently disabled on MIPS."); | 2074   printf("This test is currently disabled on MIPS."); | 
| 2088   return; | 2075   return; | 
| 2089 #endif | 2076 #endif | 
| 2090 | 2077 | 
| 2091   pid_t pid = fork(); | 2078   pid_t pid = fork(); | 
| 2092   BPF_ASSERT_NE(-1, pid); | 2079   BPF_ASSERT_NE(-1, pid); | 
| 2093   if (pid == 0) { | 2080   if (pid == 0) { | 
| 2094     pid_t my_pid = getpid(); | 2081     pid_t my_pid = getpid(); | 
| 2095     BPF_ASSERT_NE(-1, ptrace(PTRACE_TRACEME, -1, NULL, NULL)); | 2082     BPF_ASSERT_NE(-1, ptrace(PTRACE_TRACEME, -1, NULL, NULL)); | 
| 2096     BPF_ASSERT_EQ(0, raise(SIGSTOP)); | 2083     BPF_ASSERT_EQ(0, raise(SIGSTOP)); | 
| 2097     SandboxBPF sandbox; | 2084     SandboxBPF sandbox(new TraceAllPolicy); | 
| 2098     sandbox.SetSandboxPolicy(new TraceAllPolicy); | 2085     BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::SeccompLevel::SINGLE_THREADED)); | 
| 2099     BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |  | 
| 2100 | 2086 | 
| 2101     // getpid is allowed. | 2087     // getpid is allowed. | 
| 2102     BPF_ASSERT_EQ(my_pid, sys_getpid()); | 2088     BPF_ASSERT_EQ(my_pid, sys_getpid()); | 
| 2103 | 2089 | 
| 2104     // write to stdout is skipped and returns a fake value. | 2090     // write to stdout is skipped and returns a fake value. | 
| 2105     BPF_ASSERT_EQ(kExpectedReturnValue, | 2091     BPF_ASSERT_EQ(kExpectedReturnValue, | 
| 2106                   syscall(__NR_write, STDOUT_FILENO, "A", 1)); | 2092                   syscall(__NR_write, STDOUT_FILENO, "A", 1)); | 
| 2107 | 2093 | 
| 2108     // kill is rewritten to exit(kExpectedReturnValue). | 2094     // kill is rewritten to exit(kExpectedReturnValue). | 
| 2109     syscall(__NR_kill, my_pid, SIGKILL); | 2095     syscall(__NR_kill, my_pid, SIGKILL); | 
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2260   } | 2246   } | 
| 2261 | 2247 | 
| 2262   BPF_ASSERT(event->IsSignaled()); | 2248   BPF_ASSERT(event->IsSignaled()); | 
| 2263 | 2249 | 
| 2264   BlacklistNanosleepPolicy::AssertNanosleepFails(); | 2250   BlacklistNanosleepPolicy::AssertNanosleepFails(); | 
| 2265 | 2251 | 
| 2266   return NULL; | 2252   return NULL; | 
| 2267 } | 2253 } | 
| 2268 | 2254 | 
| 2269 SANDBOX_TEST(SandboxBPF, Tsync) { | 2255 SANDBOX_TEST(SandboxBPF, Tsync) { | 
| 2270   if (SandboxBPF::SupportsSeccompThreadFilterSynchronization() != | 2256   if (!(SandboxBPF::SupportsSeccompSandbox( | 
| 2271       SandboxBPF::STATUS_AVAILABLE) { | 2257           SandboxBPF::SeccompLevel::MULTI_THREADED))) { | 
| 2272     return; | 2258     return; | 
| 2273   } | 2259   } | 
| 2274 | 2260 | 
| 2275   base::WaitableEvent event(true, false); | 2261   base::WaitableEvent event(true, false); | 
| 2276 | 2262 | 
| 2277   // Create a thread on which to invoke the blocked syscall. | 2263   // Create a thread on which to invoke the blocked syscall. | 
| 2278   pthread_t thread; | 2264   pthread_t thread; | 
| 2279   BPF_ASSERT_EQ( | 2265   BPF_ASSERT_EQ( | 
| 2280       0, pthread_create(&thread, NULL, &TsyncApplyToTwoThreadsFunc, &event)); | 2266       0, pthread_create(&thread, NULL, &TsyncApplyToTwoThreadsFunc, &event)); | 
| 2281 | 2267 | 
| 2282   // Test that nanoseelp success. | 2268   // Test that nanoseelp success. | 
| 2283   const struct timespec ts = {0, 0}; | 2269   const struct timespec ts = {0, 0}; | 
| 2284   BPF_ASSERT_EQ(0, HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL))); | 2270   BPF_ASSERT_EQ(0, HANDLE_EINTR(syscall(__NR_nanosleep, &ts, NULL))); | 
| 2285 | 2271 | 
| 2286   // Engage the sandbox. | 2272   // Engage the sandbox. | 
| 2287   SandboxBPF sandbox; | 2273   SandboxBPF sandbox(new BlacklistNanosleepPolicy()); | 
| 2288   sandbox.SetSandboxPolicy(new BlacklistNanosleepPolicy()); | 2274   BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::SeccompLevel::MULTI_THREADED)); | 
| 2289   BPF_ASSERT(sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); |  | 
| 2290 | 2275 | 
| 2291   // This thread should have the filter applied as well. | 2276   // This thread should have the filter applied as well. | 
| 2292   BlacklistNanosleepPolicy::AssertNanosleepFails(); | 2277   BlacklistNanosleepPolicy::AssertNanosleepFails(); | 
| 2293 | 2278 | 
| 2294   // Signal the condition to invoke the system call. | 2279   // Signal the condition to invoke the system call. | 
| 2295   event.Signal(); | 2280   event.Signal(); | 
| 2296 | 2281 | 
| 2297   // Wait for the thread to finish. | 2282   // Wait for the thread to finish. | 
| 2298   BPF_ASSERT_EQ(0, pthread_join(thread, NULL)); | 2283   BPF_ASSERT_EQ(0, pthread_join(thread, NULL)); | 
| 2299 } | 2284 } | 
| 2300 | 2285 | 
| 2301 class AllowAllPolicy : public Policy { | 2286 class AllowAllPolicy : public Policy { | 
| 2302  public: | 2287  public: | 
| 2303   AllowAllPolicy() {} | 2288   AllowAllPolicy() {} | 
| 2304   ~AllowAllPolicy() override {} | 2289   ~AllowAllPolicy() override {} | 
| 2305 | 2290 | 
| 2306   ResultExpr EvaluateSyscall(int sysno) const override { return Allow(); } | 2291   ResultExpr EvaluateSyscall(int sysno) const override { return Allow(); } | 
| 2307 | 2292 | 
| 2308  private: | 2293  private: | 
| 2309   DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); | 2294   DISALLOW_COPY_AND_ASSIGN(AllowAllPolicy); | 
| 2310 }; | 2295 }; | 
| 2311 | 2296 | 
| 2312 SANDBOX_DEATH_TEST( | 2297 SANDBOX_DEATH_TEST( | 
| 2313     SandboxBPF, | 2298     SandboxBPF, | 
| 2314     StartMultiThreadedAsSingleThreaded, | 2299     StartMultiThreadedAsSingleThreaded, | 
| 2315     DEATH_MESSAGE("Cannot start sandbox; process is already multi-threaded")) { | 2300     DEATH_MESSAGE("Cannot start sandbox; process is already multi-threaded")) { | 
| 2316   base::Thread thread("sandbox.linux.StartMultiThreadedAsSingleThreaded"); | 2301   base::Thread thread("sandbox.linux.StartMultiThreadedAsSingleThreaded"); | 
| 2317   BPF_ASSERT(thread.Start()); | 2302   BPF_ASSERT(thread.Start()); | 
| 2318 | 2303 | 
| 2319   SandboxBPF sandbox; | 2304   SandboxBPF sandbox(new AllowAllPolicy()); | 
| 2320   sandbox.SetSandboxPolicy(new AllowAllPolicy()); | 2305   BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::SeccompLevel::SINGLE_THREADED)); | 
| 2321   BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_SINGLE_THREADED)); |  | 
| 2322 } | 2306 } | 
| 2323 | 2307 | 
| 2324 // http://crbug.com/407357 | 2308 // http://crbug.com/407357 | 
| 2325 #if !defined(THREAD_SANITIZER) | 2309 #if !defined(THREAD_SANITIZER) | 
| 2326 SANDBOX_DEATH_TEST( | 2310 SANDBOX_DEATH_TEST( | 
| 2327     SandboxBPF, | 2311     SandboxBPF, | 
| 2328     StartSingleThreadedAsMultiThreaded, | 2312     StartSingleThreadedAsMultiThreaded, | 
| 2329     DEATH_MESSAGE( | 2313     DEATH_MESSAGE( | 
| 2330         "Cannot start sandbox; process may be single-threaded when " | 2314         "Cannot start sandbox; process may be single-threaded when " | 
| 2331         "reported as not")) { | 2315         "reported as not")) { | 
| 2332   SandboxBPF sandbox; | 2316   SandboxBPF sandbox(new AllowAllPolicy()); | 
| 2333   sandbox.SetSandboxPolicy(new AllowAllPolicy()); | 2317   BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::SeccompLevel::MULTI_THREADED)); | 
| 2334   BPF_ASSERT(!sandbox.StartSandbox(SandboxBPF::PROCESS_MULTI_THREADED)); |  | 
| 2335 } | 2318 } | 
| 2336 #endif  // !defined(THREAD_SANITIZER) | 2319 #endif  // !defined(THREAD_SANITIZER) | 
| 2337 | 2320 | 
| 2338 // A stub handler for the UnsafeTrap. Never called. | 2321 // A stub handler for the UnsafeTrap. Never called. | 
| 2339 intptr_t NoOpHandler(const struct arch_seccomp_data& args, void*) { | 2322 intptr_t NoOpHandler(const struct arch_seccomp_data& args, void*) { | 
| 2340   return -1; | 2323   return -1; | 
| 2341 } | 2324 } | 
| 2342 | 2325 | 
| 2343 class UnsafeTrapWithCondPolicy : public Policy { | 2326 class UnsafeTrapWithCondPolicy : public Policy { | 
| 2344  public: | 2327  public: | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2394   BPF_ASSERT_EQ(ENOSYS, errno); | 2377   BPF_ASSERT_EQ(ENOSYS, errno); | 
| 2395 | 2378 | 
| 2396   BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); | 2379   BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); | 
| 2397   BPF_ASSERT_EQ(EPERM, errno); | 2380   BPF_ASSERT_EQ(EPERM, errno); | 
| 2398 } | 2381 } | 
| 2399 | 2382 | 
| 2400 }  // namespace | 2383 }  // namespace | 
| 2401 | 2384 | 
| 2402 }  // namespace bpf_dsl | 2385 }  // namespace bpf_dsl | 
| 2403 }  // namespace sandbox | 2386 }  // namespace sandbox | 
| OLD | NEW | 
|---|