| 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 15 matching lines...) Expand all Loading... |
| 26 #include "sandbox/linux/seccomp-bpf/syscall.h" | 26 #include "sandbox/linux/seccomp-bpf/syscall.h" |
| 27 #include "sandbox/linux/seccomp-bpf/trap.h" | 27 #include "sandbox/linux/seccomp-bpf/trap.h" |
| 28 #include "sandbox/linux/seccomp-bpf/verifier.h" | 28 #include "sandbox/linux/seccomp-bpf/verifier.h" |
| 29 #include "sandbox/linux/services/broker_process.h" | 29 #include "sandbox/linux/services/broker_process.h" |
| 30 #include "sandbox/linux/services/linux_syscalls.h" | 30 #include "sandbox/linux/services/linux_syscalls.h" |
| 31 #include "sandbox/linux/tests/unit_tests.h" | 31 #include "sandbox/linux/tests/unit_tests.h" |
| 32 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 33 | 33 |
| 34 // Workaround for Android's prctl.h file. | 34 // Workaround for Android's prctl.h file. |
| 35 #ifndef PR_GET_ENDIAN | 35 #ifndef PR_GET_ENDIAN |
| 36 #define PR_GET_ENDIAN 19 | 36 #define PR_GET_ENDIAN 19 |
| 37 #endif | 37 #endif |
| 38 #ifndef PR_CAPBSET_READ | 38 #ifndef PR_CAPBSET_READ |
| 39 #define PR_CAPBSET_READ 23 | 39 #define PR_CAPBSET_READ 23 |
| 40 #define PR_CAPBSET_DROP 24 | 40 #define PR_CAPBSET_DROP 24 |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 using namespace playground2; | 43 using namespace playground2; |
| 44 using sandbox::BrokerProcess; | 44 using sandbox::BrokerProcess; |
| 45 | 45 |
| 46 namespace { | 46 namespace { |
| 47 | 47 |
| 48 const int kExpectedReturnValue = 42; | 48 const int kExpectedReturnValue = 42; |
| 49 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING"; | 49 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING"; |
| 50 | 50 |
| 51 // This test should execute no matter whether we have kernel support. So, | 51 // This test should execute no matter whether we have kernel support. So, |
| 52 // we make it a TEST() instead of a BPF_TEST(). | 52 // we make it a TEST() instead of a BPF_TEST(). |
| 53 TEST(SandboxBpf, CallSupports) { | 53 TEST(SandboxBpf, CallSupports) { |
| 54 // We check that we don't crash, but it's ok if the kernel doesn't | 54 // We check that we don't crash, but it's ok if the kernel doesn't |
| 55 // support it. | 55 // support it. |
| 56 bool seccomp_bpf_supported = | 56 bool seccomp_bpf_supported = |
| 57 Sandbox::SupportsSeccompSandbox(-1) == Sandbox::STATUS_AVAILABLE; | 57 Sandbox::SupportsSeccompSandbox(-1) == Sandbox::STATUS_AVAILABLE; |
| 58 // We want to log whether or not seccomp BPF is actually supported | 58 // We want to log whether or not seccomp BPF is actually supported |
| 59 // since actual test coverage depends on it. | 59 // since actual test coverage depends on it. |
| 60 RecordProperty("SeccompBPFSupported", | 60 RecordProperty("SeccompBPFSupported", |
| 61 seccomp_bpf_supported ? "true." : "false."); | 61 seccomp_bpf_supported ? "true." : "false."); |
| 62 std::cout << "Seccomp BPF supported: " | 62 std::cout << "Seccomp BPF supported: " |
| 63 << (seccomp_bpf_supported ? "true." : "false.") | 63 << (seccomp_bpf_supported ? "true." : "false.") << "\n"; |
| 64 << "\n"; | |
| 65 RecordProperty("PointerSize", sizeof(void*)); | 64 RecordProperty("PointerSize", sizeof(void*)); |
| 66 std::cout << "Pointer size: " << sizeof(void*) << "\n"; | 65 std::cout << "Pointer size: " << sizeof(void*) << "\n"; |
| 67 } | 66 } |
| 68 | 67 |
| 69 SANDBOX_TEST(SandboxBpf, CallSupportsTwice) { | 68 SANDBOX_TEST(SandboxBpf, CallSupportsTwice) { |
| 70 Sandbox::SupportsSeccompSandbox(-1); | 69 Sandbox::SupportsSeccompSandbox(-1); |
| 71 Sandbox::SupportsSeccompSandbox(-1); | 70 Sandbox::SupportsSeccompSandbox(-1); |
| 72 } | 71 } |
| 73 | 72 |
| 74 // BPF_TEST does a lot of the boiler-plate code around setting up a | 73 // BPF_TEST does a lot of the boiler-plate code around setting up a |
| 75 // policy and optional passing data between the caller, the policy and | 74 // policy and optional passing data between the caller, the policy and |
| 76 // any Trap() handlers. This is great for writing short and concise tests, | 75 // any Trap() handlers. This is great for writing short and concise tests, |
| 77 // and it helps us accidentally forgetting any of the crucial steps in | 76 // 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 | 77 // setting up the sandbox. But it wouldn't hurt to have at least one test |
| 79 // that explicitly walks through all these steps. | 78 // that explicitly walks through all these steps. |
| 80 | 79 |
| 81 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void *aux) { | 80 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void* aux) { |
| 82 BPF_ASSERT(aux); | 81 BPF_ASSERT(aux); |
| 83 pid_t *pid_ptr = static_cast<pid_t *>(aux); | 82 pid_t* pid_ptr = static_cast<pid_t*>(aux); |
| 84 return (*pid_ptr)++; | 83 return (*pid_ptr)++; |
| 85 } | 84 } |
| 86 | 85 |
| 87 ErrorCode VerboseAPITestingPolicy(Sandbox *sandbox, int sysno, void *aux) { | 86 ErrorCode VerboseAPITestingPolicy(Sandbox* sandbox, int sysno, void* aux) { |
| 88 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 87 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 89 return ErrorCode(ENOSYS); | 88 return ErrorCode(ENOSYS); |
| 90 } else if (sysno == __NR_getpid) { | 89 } else if (sysno == __NR_getpid) { |
| 91 return sandbox->Trap(FakeGetPid, aux); | 90 return sandbox->Trap(FakeGetPid, aux); |
| 92 } else { | 91 } else { |
| 93 return ErrorCode(ErrorCode::ERR_ALLOWED); | 92 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 94 } | 93 } |
| 95 } | 94 } |
| 96 | 95 |
| 97 SANDBOX_TEST(SandboxBpf, DISABLE_ON_TSAN(VerboseAPITesting)) { | 96 SANDBOX_TEST(SandboxBpf, DISABLE_ON_TSAN(VerboseAPITesting)) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 109 BPF_ASSERT(test_var == 2); | 108 BPF_ASSERT(test_var == 2); |
| 110 | 109 |
| 111 // N.B.: Any future call to getpid() would corrupt the stack. | 110 // N.B.: Any future call to getpid() would corrupt the stack. |
| 112 // This is OK. The SANDBOX_TEST() macro is guaranteed to | 111 // This is OK. The SANDBOX_TEST() macro is guaranteed to |
| 113 // only ever call _exit() after the test completes. | 112 // only ever call _exit() after the test completes. |
| 114 } | 113 } |
| 115 } | 114 } |
| 116 | 115 |
| 117 // A simple blacklist test | 116 // A simple blacklist test |
| 118 | 117 |
| 119 ErrorCode BlacklistNanosleepPolicy(Sandbox *, int sysno, void *) { | 118 ErrorCode BlacklistNanosleepPolicy(Sandbox*, int sysno, void*) { |
| 120 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 119 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 121 // FIXME: we should really not have to do that in a trivial policy | 120 // FIXME: we should really not have to do that in a trivial policy |
| 122 return ErrorCode(ENOSYS); | 121 return ErrorCode(ENOSYS); |
| 123 } | 122 } |
| 124 | 123 |
| 125 switch (sysno) { | 124 switch (sysno) { |
| 126 case __NR_nanosleep: | 125 case __NR_nanosleep: |
| 127 return ErrorCode(EACCES); | 126 return ErrorCode(EACCES); |
| 128 default: | 127 default: |
| 129 return ErrorCode(ErrorCode::ERR_ALLOWED); | 128 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 130 } | 129 } |
| 131 } | 130 } |
| 132 | 131 |
| 133 BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | 132 BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { |
| 134 // nanosleep() should be denied | 133 // nanosleep() should be denied |
| 135 const struct timespec ts = {0, 0}; | 134 const struct timespec ts = {0, 0}; |
| 136 errno = 0; | 135 errno = 0; |
| 137 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 136 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| 138 BPF_ASSERT(errno == EACCES); | 137 BPF_ASSERT(errno == EACCES); |
| 139 } | 138 } |
| 140 | 139 |
| 141 // Now do a simple whitelist test | 140 // Now do a simple whitelist test |
| 142 | 141 |
| 143 ErrorCode WhitelistGetpidPolicy(Sandbox *, int sysno, void *) { | 142 ErrorCode WhitelistGetpidPolicy(Sandbox*, int sysno, void*) { |
| 144 switch (sysno) { | 143 switch (sysno) { |
| 145 case __NR_getpid: | 144 case __NR_getpid: |
| 146 case __NR_exit_group: | 145 case __NR_exit_group: |
| 147 return ErrorCode(ErrorCode::ERR_ALLOWED); | 146 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 148 default: | 147 default: |
| 149 return ErrorCode(ENOMEM); | 148 return ErrorCode(ENOMEM); |
| 150 } | 149 } |
| 151 } | 150 } |
| 152 | 151 |
| 153 BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { | 152 BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { |
| 154 // getpid() should be allowed | 153 // getpid() should be allowed |
| 155 errno = 0; | 154 errno = 0; |
| 156 BPF_ASSERT(syscall(__NR_getpid) > 0); | 155 BPF_ASSERT(syscall(__NR_getpid) > 0); |
| 157 BPF_ASSERT(errno == 0); | 156 BPF_ASSERT(errno == 0); |
| 158 | 157 |
| 159 // getpgid() should be denied | 158 // getpgid() should be denied |
| 160 BPF_ASSERT(getpgid(0) == -1); | 159 BPF_ASSERT(getpgid(0) == -1); |
| 161 BPF_ASSERT(errno == ENOMEM); | 160 BPF_ASSERT(errno == ENOMEM); |
| 162 } | 161 } |
| 163 | 162 |
| 164 // A simple blacklist policy, with a SIGSYS handler | 163 // A simple blacklist policy, with a SIGSYS handler |
| 165 | 164 |
| 166 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) { | 165 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { |
| 167 // We also check that the auxiliary data is correct | 166 // We also check that the auxiliary data is correct |
| 168 SANDBOX_ASSERT(aux); | 167 SANDBOX_ASSERT(aux); |
| 169 *(static_cast<int*>(aux)) = kExpectedReturnValue; | 168 *(static_cast<int*>(aux)) = kExpectedReturnValue; |
| 170 return -ENOMEM; | 169 return -ENOMEM; |
| 171 } | 170 } |
| 172 | 171 |
| 173 ErrorCode BlacklistNanosleepPolicySigsys(Sandbox *sandbox, int sysno, | 172 ErrorCode BlacklistNanosleepPolicySigsys(Sandbox* sandbox, |
| 174 void *aux) { | 173 int sysno, |
| 174 void* aux) { |
| 175 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 175 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 176 // FIXME: we should really not have to do that in a trivial policy | 176 // FIXME: we should really not have to do that in a trivial policy |
| 177 return ErrorCode(ENOSYS); | 177 return ErrorCode(ENOSYS); |
| 178 } | 178 } |
| 179 | 179 |
| 180 switch (sysno) { | 180 switch (sysno) { |
| 181 case __NR_nanosleep: | 181 case __NR_nanosleep: |
| 182 return sandbox->Trap(EnomemHandler, aux); | 182 return sandbox->Trap(EnomemHandler, aux); |
| 183 default: | 183 default: |
| 184 return ErrorCode(ErrorCode::ERR_ALLOWED); | 184 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 185 } | 185 } |
| 186 } | 186 } |
| 187 | 187 |
| 188 BPF_TEST(SandboxBpf, BasicBlacklistWithSigsys, | 188 BPF_TEST(SandboxBpf, |
| 189 BlacklistNanosleepPolicySigsys, int /* BPF_AUX */) { | 189 BasicBlacklistWithSigsys, |
| 190 BlacklistNanosleepPolicySigsys, |
| 191 int /* BPF_AUX */) { |
| 190 // getpid() should work properly | 192 // getpid() should work properly |
| 191 errno = 0; | 193 errno = 0; |
| 192 BPF_ASSERT(syscall(__NR_getpid) > 0); | 194 BPF_ASSERT(syscall(__NR_getpid) > 0); |
| 193 BPF_ASSERT(errno == 0); | 195 BPF_ASSERT(errno == 0); |
| 194 | 196 |
| 195 // Our Auxiliary Data, should be reset by the signal handler | 197 // Our Auxiliary Data, should be reset by the signal handler |
| 196 BPF_AUX = -1; | 198 BPF_AUX = -1; |
| 197 const struct timespec ts = {0, 0}; | 199 const struct timespec ts = {0, 0}; |
| 198 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 200 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| 199 BPF_ASSERT(errno == ENOMEM); | 201 BPF_ASSERT(errno == ENOMEM); |
| 200 | 202 |
| 201 // We expect the signal handler to modify AuxData | 203 // We expect the signal handler to modify AuxData |
| 202 BPF_ASSERT(BPF_AUX == kExpectedReturnValue); | 204 BPF_ASSERT(BPF_AUX == kExpectedReturnValue); |
| 203 } | 205 } |
| 204 | 206 |
| 205 // A simple test that verifies we can return arbitrary errno values. | 207 // A simple test that verifies we can return arbitrary errno values. |
| 206 | 208 |
| 207 ErrorCode ErrnoTestPolicy(Sandbox *, int sysno, void *) { | 209 ErrorCode ErrnoTestPolicy(Sandbox*, int sysno, void*) { |
| 208 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 210 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 209 // FIXME: we should really not have to do that in a trivial policy | 211 // FIXME: we should really not have to do that in a trivial policy |
| 210 return ErrorCode(ENOSYS); | 212 return ErrorCode(ENOSYS); |
| 211 } | 213 } |
| 212 | 214 |
| 213 switch (sysno) { | 215 switch (sysno) { |
| 214 case __NR_dup2: | 216 case __NR_dup2: |
| 215 // Pretend that dup2() worked, but don't actually do anything. | 217 // Pretend that dup2() worked, but don't actually do anything. |
| 216 return ErrorCode(0); | 218 return ErrorCode(0); |
| 217 case __NR_setuid: | 219 case __NR_setuid: |
| 218 #if defined(__NR_setuid32) | 220 #if defined(__NR_setuid32) |
| 219 case __NR_setuid32: | 221 case __NR_setuid32: |
| 220 #endif | 222 #endif |
| 221 // Return errno = 1. | 223 // Return errno = 1. |
| 222 return ErrorCode(1); | 224 return ErrorCode(1); |
| 223 case __NR_setgid: | 225 case __NR_setgid: |
| 224 #if defined(__NR_setgid32) | 226 #if defined(__NR_setgid32) |
| 225 case __NR_setgid32: | 227 case __NR_setgid32: |
| 226 #endif | 228 #endif |
| 227 // Return maximum errno value (typically 4095). | 229 // Return maximum errno value (typically 4095). |
| 228 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); | 230 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); |
| 229 case __NR_uname: | 231 case __NR_uname: |
| 230 // Return errno = 42; | 232 // Return errno = 42; |
| 231 return ErrorCode(42); | 233 return ErrorCode(42); |
| 232 default: | 234 default: |
| 233 return ErrorCode(ErrorCode::ERR_ALLOWED); | 235 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 234 } | 236 } |
| 235 } | 237 } |
| 236 | 238 |
| 237 BPF_TEST(SandboxBpf, ErrnoTest, ErrnoTestPolicy) { | 239 BPF_TEST(SandboxBpf, ErrnoTest, ErrnoTestPolicy) { |
| 238 // Verify that dup2() returns success, but doesn't actually run. | 240 // Verify that dup2() returns success, but doesn't actually run. |
| 239 int fds[4]; | 241 int fds[4]; |
| 240 BPF_ASSERT(pipe(fds) == 0); | 242 BPF_ASSERT(pipe(fds) == 0); |
| 241 BPF_ASSERT(pipe(fds+2) == 0); | 243 BPF_ASSERT(pipe(fds + 2) == 0); |
| 242 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); | 244 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); |
| 243 char buf[1] = { }; | 245 char buf[1] = {}; |
| 244 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); | 246 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); |
| 245 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); | 247 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); |
| 246 BPF_ASSERT(read(fds[0], buf, 1) == 1); | 248 BPF_ASSERT(read(fds[0], buf, 1) == 1); |
| 247 | 249 |
| 248 // If dup2() executed, we will read \xAA, but it dup2() has been turned | 250 // If dup2() executed, we will read \xAA, but it dup2() has been turned |
| 249 // into a no-op by our policy, then we will read \x55. | 251 // into a no-op by our policy, then we will read \x55. |
| 250 BPF_ASSERT(buf[0] == '\x55'); | 252 BPF_ASSERT(buf[0] == '\x55'); |
| 251 | 253 |
| 252 // Verify that we can return the minimum and maximum errno values. | 254 // Verify that we can return the minimum and maximum errno values. |
| 253 errno = 0; | 255 errno = 0; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 269 | 271 |
| 270 // Finally, test an errno in between the minimum and maximum. | 272 // Finally, test an errno in between the minimum and maximum. |
| 271 errno = 0; | 273 errno = 0; |
| 272 struct utsname uts_buf; | 274 struct utsname uts_buf; |
| 273 BPF_ASSERT(uname(&uts_buf) == -1); | 275 BPF_ASSERT(uname(&uts_buf) == -1); |
| 274 BPF_ASSERT(errno == 42); | 276 BPF_ASSERT(errno == 42); |
| 275 } | 277 } |
| 276 | 278 |
| 277 // Testing the stacking of two sandboxes | 279 // Testing the stacking of two sandboxes |
| 278 | 280 |
| 279 ErrorCode StackingPolicyPartOne(Sandbox *sandbox, int sysno, void *) { | 281 ErrorCode StackingPolicyPartOne(Sandbox* sandbox, int sysno, void*) { |
| 280 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 282 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 281 return ErrorCode(ENOSYS); | 283 return ErrorCode(ENOSYS); |
| 282 } | 284 } |
| 283 | 285 |
| 284 switch (sysno) { | 286 switch (sysno) { |
| 285 case __NR_getppid: | 287 case __NR_getppid: |
| 286 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 288 return sandbox->Cond(0, |
| 289 ErrorCode::TP_32BIT, |
| 290 ErrorCode::OP_EQUAL, |
| 291 0, |
| 287 ErrorCode(ErrorCode::ERR_ALLOWED), | 292 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 288 ErrorCode(EPERM)); | 293 ErrorCode(EPERM)); |
| 289 default: | 294 default: |
| 290 return ErrorCode(ErrorCode::ERR_ALLOWED); | 295 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 291 } | 296 } |
| 292 } | 297 } |
| 293 | 298 |
| 294 ErrorCode StackingPolicyPartTwo(Sandbox *sandbox, int sysno, void *) { | 299 ErrorCode StackingPolicyPartTwo(Sandbox* sandbox, int sysno, void*) { |
| 295 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 300 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 296 return ErrorCode(ENOSYS); | 301 return ErrorCode(ENOSYS); |
| 297 } | 302 } |
| 298 | 303 |
| 299 switch (sysno) { | 304 switch (sysno) { |
| 300 case __NR_getppid: | 305 case __NR_getppid: |
| 301 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 306 return sandbox->Cond(0, |
| 307 ErrorCode::TP_32BIT, |
| 308 ErrorCode::OP_EQUAL, |
| 309 0, |
| 302 ErrorCode(EINVAL), | 310 ErrorCode(EINVAL), |
| 303 ErrorCode(ErrorCode::ERR_ALLOWED)); | 311 ErrorCode(ErrorCode::ERR_ALLOWED)); |
| 304 default: | 312 default: |
| 305 return ErrorCode(ErrorCode::ERR_ALLOWED); | 313 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 306 } | 314 } |
| 307 } | 315 } |
| 308 | 316 |
| 309 BPF_TEST(SandboxBpf, StackingPolicy, StackingPolicyPartOne) { | 317 BPF_TEST(SandboxBpf, StackingPolicy, StackingPolicyPartOne) { |
| 310 errno = 0; | 318 errno = 0; |
| 311 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); | 319 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 336 // We try to make sure we exercise optimizations in the BPF compiler. We make | 344 // We try to make sure we exercise optimizations in the BPF compiler. We make |
| 337 // sure that the compiler can have an opportunity to coalesce syscalls with | 345 // sure that the compiler can have an opportunity to coalesce syscalls with |
| 338 // contiguous numbers and we also make sure that disjoint sets can return the | 346 // contiguous numbers and we also make sure that disjoint sets can return the |
| 339 // same errno. | 347 // same errno. |
| 340 int SysnoToRandomErrno(int sysno) { | 348 int SysnoToRandomErrno(int sysno) { |
| 341 // Small contiguous sets of 3 system calls return an errno equal to the | 349 // Small contiguous sets of 3 system calls return an errno equal to the |
| 342 // index of that set + 1 (so that we never return a NUL errno). | 350 // index of that set + 1 (so that we never return a NUL errno). |
| 343 return ((sysno & ~3) >> 2) % 29 + 1; | 351 return ((sysno & ~3) >> 2) % 29 + 1; |
| 344 } | 352 } |
| 345 | 353 |
| 346 ErrorCode SyntheticPolicy(Sandbox *, int sysno, void *) { | 354 ErrorCode SyntheticPolicy(Sandbox*, int sysno, void*) { |
| 347 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 355 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 348 // FIXME: we should really not have to do that in a trivial policy | 356 // FIXME: we should really not have to do that in a trivial policy |
| 349 return ErrorCode(ENOSYS); | 357 return ErrorCode(ENOSYS); |
| 350 } | 358 } |
| 351 | 359 |
| 352 // TODO(jorgelo): remove this once the new code generator lands. | 360 // TODO(jorgelo): remove this once the new code generator lands. |
| 353 #if defined(__arm__) | 361 #if defined(__arm__) |
| 354 if (sysno > static_cast<int>(MAX_PUBLIC_SYSCALL)) { | 362 if (sysno > static_cast<int>(MAX_PUBLIC_SYSCALL)) { |
| 355 return ErrorCode(ENOSYS); | 363 return ErrorCode(ENOSYS); |
| 356 } | 364 } |
| 357 #endif | 365 #endif |
| 358 | 366 |
| 359 if (sysno == __NR_exit_group || sysno == __NR_write) { | 367 if (sysno == __NR_exit_group || sysno == __NR_write) { |
| 360 // exit_group() is special, we really need it to work. | 368 // exit_group() is special, we really need it to work. |
| 361 // write() is needed for BPF_ASSERT() to report a useful error message. | 369 // write() is needed for BPF_ASSERT() to report a useful error message. |
| 362 return ErrorCode(ErrorCode::ERR_ALLOWED); | 370 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 363 } else { | 371 } else { |
| 364 return ErrorCode(SysnoToRandomErrno(sysno)); | 372 return ErrorCode(SysnoToRandomErrno(sysno)); |
| 365 } | 373 } |
| 366 } | 374 } |
| 367 | 375 |
| 368 BPF_TEST(SandboxBpf, SyntheticPolicy, SyntheticPolicy) { | 376 BPF_TEST(SandboxBpf, SyntheticPolicy, SyntheticPolicy) { |
| 369 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int | 377 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int |
| 370 // overflow. | 378 // overflow. |
| 371 BPF_ASSERT( | 379 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= |
| 372 std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= | 380 static_cast<int>(MAX_PUBLIC_SYSCALL)); |
| 373 static_cast<int>(MAX_PUBLIC_SYSCALL)); | |
| 374 | 381 |
| 375 for (int syscall_number = static_cast<int>(MIN_SYSCALL); | 382 for (int syscall_number = static_cast<int>(MIN_SYSCALL); |
| 376 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); | 383 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); |
| 377 ++syscall_number) { | 384 ++syscall_number) { |
| 378 if (syscall_number == __NR_exit_group || | 385 if (syscall_number == __NR_exit_group || syscall_number == __NR_write) { |
| 379 syscall_number == __NR_write) { | |
| 380 // exit_group() is special | 386 // exit_group() is special |
| 381 continue; | 387 continue; |
| 382 } | 388 } |
| 383 errno = 0; | 389 errno = 0; |
| 384 BPF_ASSERT(syscall(syscall_number) == -1); | 390 BPF_ASSERT(syscall(syscall_number) == -1); |
| 385 BPF_ASSERT(errno == SysnoToRandomErrno(syscall_number)); | 391 BPF_ASSERT(errno == SysnoToRandomErrno(syscall_number)); |
| 386 } | 392 } |
| 387 } | 393 } |
| 388 | 394 |
| 389 #if defined(__arm__) | 395 #if defined(__arm__) |
| 390 // A simple policy that tests whether ARM private system calls are supported | 396 // A simple policy that tests whether ARM private system calls are supported |
| 391 // by our BPF compiler and by the BPF interpreter in the kernel. | 397 // by our BPF compiler and by the BPF interpreter in the kernel. |
| 392 | 398 |
| 393 // For ARM private system calls, return an errno equal to their offset from | 399 // For ARM private system calls, return an errno equal to their offset from |
| 394 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). | 400 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). |
| 395 int ArmPrivateSysnoToErrno(int sysno) { | 401 int ArmPrivateSysnoToErrno(int sysno) { |
| 396 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && | 402 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && |
| 397 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 403 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
| 398 return (sysno - MIN_PRIVATE_SYSCALL) + 1; | 404 return (sysno - MIN_PRIVATE_SYSCALL) + 1; |
| 399 } else { | 405 } else { |
| 400 return ENOSYS; | 406 return ENOSYS; |
| 401 } | 407 } |
| 402 } | 408 } |
| 403 | 409 |
| 404 ErrorCode ArmPrivatePolicy(Sandbox *, int sysno, void *) { | 410 ErrorCode ArmPrivatePolicy(Sandbox*, int sysno, void*) { |
| 405 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 411 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 406 // FIXME: we should really not have to do that in a trivial policy. | 412 // FIXME: we should really not have to do that in a trivial policy. |
| 407 return ErrorCode(ENOSYS); | 413 return ErrorCode(ENOSYS); |
| 408 } | 414 } |
| 409 | 415 |
| 410 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual | 416 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual |
| 411 // ARM private system calls. | 417 // ARM private system calls. |
| 412 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && | 418 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && |
| 413 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 419 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
| 414 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); | 420 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); |
| 415 } else { | 421 } else { |
| 416 return ErrorCode(ErrorCode::ERR_ALLOWED); | 422 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 417 } | 423 } |
| 418 } | 424 } |
| 419 | 425 |
| 420 BPF_TEST(SandboxBpf, ArmPrivatePolicy, ArmPrivatePolicy) { | 426 BPF_TEST(SandboxBpf, ArmPrivatePolicy, ArmPrivatePolicy) { |
| 421 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); | 427 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); |
| 422 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); | 428 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); |
| 423 ++syscall_number) { | 429 ++syscall_number) { |
| 424 errno = 0; | 430 errno = 0; |
| 425 BPF_ASSERT(syscall(syscall_number) == -1); | 431 BPF_ASSERT(syscall(syscall_number) == -1); |
| 426 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); | 432 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); |
| 427 } | 433 } |
| 428 } | 434 } |
| 429 #endif // defined(__arm__) | 435 #endif // defined(__arm__) |
| 430 | 436 |
| 431 intptr_t CountSyscalls(const struct arch_seccomp_data& args, void *aux) { | 437 intptr_t CountSyscalls(const struct arch_seccomp_data& args, void* aux) { |
| 432 // Count all invocations of our callback function. | 438 // Count all invocations of our callback function. |
| 433 ++*reinterpret_cast<int *>(aux); | 439 ++*reinterpret_cast<int*>(aux); |
| 434 | 440 |
| 435 // Verify that within the callback function all filtering is temporarily | 441 // Verify that within the callback function all filtering is temporarily |
| 436 // disabled. | 442 // disabled. |
| 437 BPF_ASSERT(syscall(__NR_getpid) > 1); | 443 BPF_ASSERT(syscall(__NR_getpid) > 1); |
| 438 | 444 |
| 439 // Verify that we can now call the underlying system call without causing | 445 // Verify that we can now call the underlying system call without causing |
| 440 // infinite recursion. | 446 // infinite recursion. |
| 441 return Sandbox::ForwardSyscall(args); | 447 return Sandbox::ForwardSyscall(args); |
| 442 } | 448 } |
| 443 | 449 |
| 444 ErrorCode GreyListedPolicy(Sandbox *sandbox, int sysno, void *aux) { | 450 ErrorCode GreyListedPolicy(Sandbox* sandbox, int sysno, void* aux) { |
| 445 // The use of UnsafeTrap() causes us to print a warning message. This is | 451 // The use of UnsafeTrap() causes us to print a warning message. This is |
| 446 // generally desirable, but it results in the unittest failing, as it doesn't | 452 // generally desirable, but it results in the unittest failing, as it doesn't |
| 447 // expect any messages on "stderr". So, temporarily disable messages. The | 453 // expect any messages on "stderr". So, temporarily disable messages. The |
| 448 // BPF_TEST() is guaranteed to turn messages back on, after the policy | 454 // BPF_TEST() is guaranteed to turn messages back on, after the policy |
| 449 // function has completed. | 455 // function has completed. |
| 450 setenv(kSandboxDebuggingEnv, "t", 0); | 456 setenv(kSandboxDebuggingEnv, "t", 0); |
| 451 Die::SuppressInfoMessages(true); | 457 Die::SuppressInfoMessages(true); |
| 452 | 458 |
| 453 // Some system calls must always be allowed, if our policy wants to make | 459 // Some system calls must always be allowed, if our policy wants to make |
| 454 // use of UnsafeTrap() | 460 // use of UnsafeTrap() |
| 455 if (sysno == __NR_rt_sigprocmask || | 461 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn |
| 456 sysno == __NR_rt_sigreturn | |
| 457 #if defined(__NR_sigprocmask) | 462 #if defined(__NR_sigprocmask) |
| 458 || sysno == __NR_sigprocmask | 463 || |
| 464 sysno == __NR_sigprocmask |
| 459 #endif | 465 #endif |
| 460 #if defined(__NR_sigreturn) | 466 #if defined(__NR_sigreturn) |
| 461 || sysno == __NR_sigreturn | 467 || |
| 468 sysno == __NR_sigreturn |
| 462 #endif | 469 #endif |
| 463 ) { | 470 ) { |
| 464 return ErrorCode(ErrorCode::ERR_ALLOWED); | 471 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 465 } else if (sysno == __NR_getpid) { | 472 } else if (sysno == __NR_getpid) { |
| 466 // Disallow getpid() | 473 // Disallow getpid() |
| 467 return ErrorCode(EPERM); | 474 return ErrorCode(EPERM); |
| 468 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 475 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
| 469 // Allow (and count) all other system calls. | 476 // Allow (and count) all other system calls. |
| 470 return sandbox->UnsafeTrap(CountSyscalls, aux); | 477 return sandbox->UnsafeTrap(CountSyscalls, aux); |
| 471 } else { | 478 } else { |
| 472 return ErrorCode(ENOSYS); | 479 return ErrorCode(ENOSYS); |
| 473 } | 480 } |
| 474 } | 481 } |
| 475 | 482 |
| 476 BPF_TEST(SandboxBpf, GreyListedPolicy, | 483 BPF_TEST(SandboxBpf, GreyListedPolicy, GreyListedPolicy, int /* BPF_AUX */) { |
| 477 GreyListedPolicy, int /* BPF_AUX */) { | |
| 478 BPF_ASSERT(syscall(__NR_getpid) == -1); | 484 BPF_ASSERT(syscall(__NR_getpid) == -1); |
| 479 BPF_ASSERT(errno == EPERM); | 485 BPF_ASSERT(errno == EPERM); |
| 480 BPF_ASSERT(BPF_AUX == 0); | 486 BPF_ASSERT(BPF_AUX == 0); |
| 481 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); | 487 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); |
| 482 BPF_ASSERT(BPF_AUX == 2); | 488 BPF_ASSERT(BPF_AUX == 2); |
| 483 char name[17] = { }; | 489 char name[17] = {}; |
| 484 BPF_ASSERT(!syscall(__NR_prctl, PR_GET_NAME, name, (void *)NULL, | 490 BPF_ASSERT(!syscall(__NR_prctl, |
| 485 (void *)NULL, (void *)NULL)); | 491 PR_GET_NAME, |
| 492 name, |
| 493 (void*)NULL, |
| 494 (void*)NULL, |
| 495 (void*)NULL)); |
| 486 BPF_ASSERT(BPF_AUX == 3); | 496 BPF_ASSERT(BPF_AUX == 3); |
| 487 BPF_ASSERT(*name); | 497 BPF_ASSERT(*name); |
| 488 } | 498 } |
| 489 | 499 |
| 490 SANDBOX_TEST(SandboxBpf, EnableUnsafeTrapsInSigSysHandler) { | 500 SANDBOX_TEST(SandboxBpf, EnableUnsafeTrapsInSigSysHandler) { |
| 491 // Disabling warning messages that could confuse our test framework. | 501 // Disabling warning messages that could confuse our test framework. |
| 492 setenv(kSandboxDebuggingEnv, "t", 0); | 502 setenv(kSandboxDebuggingEnv, "t", 0); |
| 493 Die::SuppressInfoMessages(true); | 503 Die::SuppressInfoMessages(true); |
| 494 | 504 |
| 495 unsetenv(kSandboxDebuggingEnv); | 505 unsetenv(kSandboxDebuggingEnv); |
| 496 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); | 506 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); |
| 497 setenv(kSandboxDebuggingEnv, "", 1); | 507 setenv(kSandboxDebuggingEnv, "", 1); |
| 498 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); | 508 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); |
| 499 setenv(kSandboxDebuggingEnv, "t", 1); | 509 setenv(kSandboxDebuggingEnv, "t", 1); |
| 500 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == true); | 510 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == true); |
| 501 } | 511 } |
| 502 | 512 |
| 503 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void *) { | 513 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { |
| 504 if (args.args[0] == PR_CAPBSET_DROP && | 514 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { |
| 505 static_cast<int>(args.args[1]) == -1) { | |
| 506 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always | 515 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always |
| 507 // return an error. But our handler allows this call. | 516 // return an error. But our handler allows this call. |
| 508 return 0; | 517 return 0; |
| 509 } else { | 518 } else { |
| 510 return Sandbox::ForwardSyscall(args); | 519 return Sandbox::ForwardSyscall(args); |
| 511 } | 520 } |
| 512 } | 521 } |
| 513 | 522 |
| 514 ErrorCode PrctlPolicy(Sandbox *sandbox, int sysno, void *aux) { | 523 ErrorCode PrctlPolicy(Sandbox* sandbox, int sysno, void* aux) { |
| 515 setenv(kSandboxDebuggingEnv, "t", 0); | 524 setenv(kSandboxDebuggingEnv, "t", 0); |
| 516 Die::SuppressInfoMessages(true); | 525 Die::SuppressInfoMessages(true); |
| 517 | 526 |
| 518 if (sysno == __NR_prctl) { | 527 if (sysno == __NR_prctl) { |
| 519 // Handle prctl() inside an UnsafeTrap() | 528 // Handle prctl() inside an UnsafeTrap() |
| 520 return sandbox->UnsafeTrap(PrctlHandler, NULL); | 529 return sandbox->UnsafeTrap(PrctlHandler, NULL); |
| 521 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 530 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
| 522 // Allow all other system calls. | 531 // Allow all other system calls. |
| 523 return ErrorCode(ErrorCode::ERR_ALLOWED); | 532 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 524 } else { | 533 } else { |
| 525 return ErrorCode(ENOSYS); | 534 return ErrorCode(ENOSYS); |
| 526 } | 535 } |
| 527 } | 536 } |
| 528 | 537 |
| 529 BPF_TEST(SandboxBpf, ForwardSyscall, PrctlPolicy) { | 538 BPF_TEST(SandboxBpf, ForwardSyscall, PrctlPolicy) { |
| 530 // This call should never be allowed. But our policy will intercept it and | 539 // This call should never be allowed. But our policy will intercept it and |
| 531 // let it pass successfully. | 540 // let it pass successfully. |
| 532 BPF_ASSERT(!prctl(PR_CAPBSET_DROP, -1, (void *)NULL, (void *)NULL, | 541 BPF_ASSERT( |
| 533 (void *)NULL)); | 542 !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL)); |
| 534 | 543 |
| 535 // Verify that the call will fail, if it makes it all the way to the kernel. | 544 // Verify that the call will fail, if it makes it all the way to the kernel. |
| 536 BPF_ASSERT(prctl(PR_CAPBSET_DROP, -2, (void *)NULL, (void *)NULL, | 545 BPF_ASSERT( |
| 537 (void *)NULL) == -1); | 546 prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1); |
| 538 | 547 |
| 539 // And verify that other uses of prctl() work just fine. | 548 // And verify that other uses of prctl() work just fine. |
| 540 char name[17] = { }; | 549 char name[17] = {}; |
| 541 BPF_ASSERT(!syscall(__NR_prctl, PR_GET_NAME, name, (void *)NULL, | 550 BPF_ASSERT(!syscall(__NR_prctl, |
| 542 (void *)NULL, (void *)NULL)); | 551 PR_GET_NAME, |
| 552 name, |
| 553 (void*)NULL, |
| 554 (void*)NULL, |
| 555 (void*)NULL)); |
| 543 BPF_ASSERT(*name); | 556 BPF_ASSERT(*name); |
| 544 | 557 |
| 545 // Finally, verify that system calls other than prctl() are completely | 558 // Finally, verify that system calls other than prctl() are completely |
| 546 // unaffected by our policy. | 559 // unaffected by our policy. |
| 547 struct utsname uts = { }; | 560 struct utsname uts = {}; |
| 548 BPF_ASSERT(!uname(&uts)); | 561 BPF_ASSERT(!uname(&uts)); |
| 549 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); | 562 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); |
| 550 } | 563 } |
| 551 | 564 |
| 552 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void *) { | 565 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { |
| 553 return Sandbox::ForwardSyscall(args); | 566 return Sandbox::ForwardSyscall(args); |
| 554 } | 567 } |
| 555 | 568 |
| 556 ErrorCode RedirectAllSyscallsPolicy(Sandbox *sandbox, int sysno, void *aux) { | 569 ErrorCode RedirectAllSyscallsPolicy(Sandbox* sandbox, int sysno, void* aux) { |
| 557 setenv(kSandboxDebuggingEnv, "t", 0); | 570 setenv(kSandboxDebuggingEnv, "t", 0); |
| 558 Die::SuppressInfoMessages(true); | 571 Die::SuppressInfoMessages(true); |
| 559 | 572 |
| 560 // Some system calls must always be allowed, if our policy wants to make | 573 // Some system calls must always be allowed, if our policy wants to make |
| 561 // use of UnsafeTrap() | 574 // use of UnsafeTrap() |
| 562 if (sysno == __NR_rt_sigprocmask || | 575 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn |
| 563 sysno == __NR_rt_sigreturn | |
| 564 #if defined(__NR_sigprocmask) | 576 #if defined(__NR_sigprocmask) |
| 565 || sysno == __NR_sigprocmask | 577 || |
| 578 sysno == __NR_sigprocmask |
| 566 #endif | 579 #endif |
| 567 #if defined(__NR_sigreturn) | 580 #if defined(__NR_sigreturn) |
| 568 || sysno == __NR_sigreturn | 581 || |
| 582 sysno == __NR_sigreturn |
| 569 #endif | 583 #endif |
| 570 ) { | 584 ) { |
| 571 return ErrorCode(ErrorCode::ERR_ALLOWED); | 585 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 572 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 586 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
| 573 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux); | 587 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux); |
| 574 } else { | 588 } else { |
| 575 return ErrorCode(ENOSYS); | 589 return ErrorCode(ENOSYS); |
| 576 } | 590 } |
| 577 } | 591 } |
| 578 | 592 |
| 579 int bus_handler_fd_ = -1; | 593 int bus_handler_fd_ = -1; |
| 580 | 594 |
| 581 void SigBusHandler(int, siginfo_t *info, void *void_context) { | 595 void SigBusHandler(int, siginfo_t* info, void* void_context) { |
| 582 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); | 596 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); |
| 583 } | 597 } |
| 584 | 598 |
| 585 BPF_TEST(SandboxBpf, SigBus, RedirectAllSyscallsPolicy) { | 599 BPF_TEST(SandboxBpf, SigBus, RedirectAllSyscallsPolicy) { |
| 586 // We use the SIGBUS bit in the signal mask as a thread-local boolean | 600 // We use the SIGBUS bit in the signal mask as a thread-local boolean |
| 587 // value in the implementation of UnsafeTrap(). This is obviously a bit | 601 // value in the implementation of UnsafeTrap(). This is obviously a bit |
| 588 // of a hack that could conceivably interfere with code that uses SIGBUS | 602 // of a hack that could conceivably interfere with code that uses SIGBUS |
| 589 // in more traditional ways. This test verifies that basic functionality | 603 // in more traditional ways. This test verifies that basic functionality |
| 590 // of SIGBUS is not impacted, but it is certainly possibly to construe | 604 // of SIGBUS is not impacted, but it is certainly possibly to construe |
| 591 // more complex uses of signals where our use of the SIGBUS mask is not | 605 // more complex uses of signals where our use of the SIGBUS mask is not |
| 592 // 100% transparent. This is expected behavior. | 606 // 100% transparent. This is expected behavior. |
| 593 int fds[2]; | 607 int fds[2]; |
| 594 BPF_ASSERT(pipe(fds) == 0); | 608 BPF_ASSERT(pipe(fds) == 0); |
| 595 bus_handler_fd_ = fds[1]; | 609 bus_handler_fd_ = fds[1]; |
| 596 struct sigaction sa = { }; | 610 struct sigaction sa = {}; |
| 597 sa.sa_sigaction = SigBusHandler; | 611 sa.sa_sigaction = SigBusHandler; |
| 598 sa.sa_flags = SA_SIGINFO; | 612 sa.sa_flags = SA_SIGINFO; |
| 599 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); | 613 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); |
| 600 raise(SIGBUS); | 614 raise(SIGBUS); |
| 601 char c = '\000'; | 615 char c = '\000'; |
| 602 BPF_ASSERT(read(fds[0], &c, 1) == 1); | 616 BPF_ASSERT(read(fds[0], &c, 1) == 1); |
| 603 BPF_ASSERT(close(fds[0]) == 0); | 617 BPF_ASSERT(close(fds[0]) == 0); |
| 604 BPF_ASSERT(close(fds[1]) == 0); | 618 BPF_ASSERT(close(fds[1]) == 0); |
| 605 BPF_ASSERT(c == 0x55); | 619 BPF_ASSERT(c == 0x55); |
| 606 } | 620 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 622 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. | 636 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. |
| 623 sigemptyset(&mask0); | 637 sigemptyset(&mask0); |
| 624 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); | 638 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); |
| 625 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); | 639 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); |
| 626 | 640 |
| 627 // Try again, and this time we verify that we can block it. This | 641 // Try again, and this time we verify that we can block it. This |
| 628 // requires a second call to sigprocmask(). | 642 // requires a second call to sigprocmask(). |
| 629 sigaddset(&mask0, SIGUSR2); | 643 sigaddset(&mask0, SIGUSR2); |
| 630 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); | 644 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); |
| 631 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); | 645 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); |
| 632 BPF_ASSERT( sigismember(&mask2, SIGUSR2)); | 646 BPF_ASSERT(sigismember(&mask2, SIGUSR2)); |
| 633 } | 647 } |
| 634 | 648 |
| 635 BPF_TEST(SandboxBpf, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { | 649 BPF_TEST(SandboxBpf, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { |
| 636 // An UnsafeTrap() (or for that matter, a Trap()) has to report error | 650 // An UnsafeTrap() (or for that matter, a Trap()) has to report error |
| 637 // conditions by returning an exit code in the range -1..-4096. This | 651 // conditions by returning an exit code in the range -1..-4096. This |
| 638 // should happen automatically if using ForwardSyscall(). If the TrapFnc() | 652 // should happen automatically if using ForwardSyscall(). If the TrapFnc() |
| 639 // uses some other method to make system calls, then it is responsible | 653 // uses some other method to make system calls, then it is responsible |
| 640 // for computing the correct return code. | 654 // for computing the correct return code. |
| 641 // This test verifies that ForwardSyscall() does the correct thing. | 655 // This test verifies that ForwardSyscall() does the correct thing. |
| 642 | 656 |
| 643 // The glibc system wrapper will ultimately set errno for us. So, from normal | 657 // The glibc system wrapper will ultimately set errno for us. So, from normal |
| 644 // userspace, all of this should be completely transparent. | 658 // userspace, all of this should be completely transparent. |
| 645 errno = 0; | 659 errno = 0; |
| 646 BPF_ASSERT(close(-1) == -1); | 660 BPF_ASSERT(close(-1) == -1); |
| 647 BPF_ASSERT(errno == EBADF); | 661 BPF_ASSERT(errno == EBADF); |
| 648 | 662 |
| 649 // Explicitly avoid the glibc wrapper. This is not normally the way anybody | 663 // Explicitly avoid the glibc wrapper. This is not normally the way anybody |
| 650 // would make system calls, but it allows us to verify that we don't | 664 // would make system calls, but it allows us to verify that we don't |
| 651 // accidentally mess with errno, when we shouldn't. | 665 // accidentally mess with errno, when we shouldn't. |
| 652 errno = 0; | 666 errno = 0; |
| 653 struct arch_seccomp_data args = { }; | 667 struct arch_seccomp_data args = {}; |
| 654 args.nr = __NR_close; | 668 args.nr = __NR_close; |
| 655 args.args[0] = -1; | 669 args.args[0] = -1; |
| 656 BPF_ASSERT(Sandbox::ForwardSyscall(args) == -EBADF); | 670 BPF_ASSERT(Sandbox::ForwardSyscall(args) == -EBADF); |
| 657 BPF_ASSERT(errno == 0); | 671 BPF_ASSERT(errno == 0); |
| 658 } | 672 } |
| 659 | 673 |
| 660 // Test a trap handler that makes use of a broker process to open(). | 674 // Test a trap handler that makes use of a broker process to open(). |
| 661 | 675 |
| 662 class InitializedOpenBroker { | 676 class InitializedOpenBroker { |
| 663 public: | 677 public: |
| 664 InitializedOpenBroker() : initialized_(false) { | 678 InitializedOpenBroker() : initialized_(false) { |
| 665 std::vector<std::string> allowed_files; | 679 std::vector<std::string> allowed_files; |
| 666 allowed_files.push_back("/proc/allowed"); | 680 allowed_files.push_back("/proc/allowed"); |
| 667 allowed_files.push_back("/proc/cpuinfo"); | 681 allowed_files.push_back("/proc/cpuinfo"); |
| 668 | 682 |
| 669 broker_process_.reset(new BrokerProcess(EPERM, | 683 broker_process_.reset( |
| 670 allowed_files, | 684 new BrokerProcess(EPERM, allowed_files, std::vector<std::string>())); |
| 671 std::vector<std::string>())); | |
| 672 BPF_ASSERT(broker_process() != NULL); | 685 BPF_ASSERT(broker_process() != NULL); |
| 673 BPF_ASSERT(broker_process_->Init(NULL)); | 686 BPF_ASSERT(broker_process_->Init(NULL)); |
| 674 | 687 |
| 675 initialized_ = true; | 688 initialized_ = true; |
| 676 } | 689 } |
| 677 bool initialized() { return initialized_; } | 690 bool initialized() { return initialized_; } |
| 678 class BrokerProcess* broker_process() { return broker_process_.get(); } | 691 class BrokerProcess* broker_process() { return broker_process_.get(); } |
| 692 |
| 679 private: | 693 private: |
| 680 bool initialized_; | 694 bool initialized_; |
| 681 scoped_ptr<class BrokerProcess> broker_process_; | 695 scoped_ptr<class BrokerProcess> broker_process_; |
| 682 DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker); | 696 DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker); |
| 683 }; | 697 }; |
| 684 | 698 |
| 685 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args, | 699 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args, |
| 686 void *aux) { | 700 void* aux) { |
| 687 BPF_ASSERT(aux); | 701 BPF_ASSERT(aux); |
| 688 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux); | 702 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux); |
| 689 switch(args.nr) { | 703 switch (args.nr) { |
| 690 case __NR_access: | 704 case __NR_access: |
| 691 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), | 705 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), |
| 692 static_cast<int>(args.args[1])); | 706 static_cast<int>(args.args[1])); |
| 693 case __NR_open: | 707 case __NR_open: |
| 694 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]), | 708 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]), |
| 695 static_cast<int>(args.args[1])); | 709 static_cast<int>(args.args[1])); |
| 696 case __NR_openat: | 710 case __NR_openat: |
| 697 // We only call open() so if we arrive here, it's because glibc uses | 711 // We only call open() so if we arrive here, it's because glibc uses |
| 698 // the openat() system call. | 712 // the openat() system call. |
| 699 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); | 713 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); |
| 700 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), | 714 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), |
| 701 static_cast<int>(args.args[2])); | 715 static_cast<int>(args.args[2])); |
| 702 default: | 716 default: |
| 703 BPF_ASSERT(false); | 717 BPF_ASSERT(false); |
| 704 return -ENOSYS; | 718 return -ENOSYS; |
| 705 } | 719 } |
| 706 } | 720 } |
| 707 | 721 |
| 708 ErrorCode DenyOpenPolicy(Sandbox *sandbox, int sysno, void *aux) { | 722 ErrorCode DenyOpenPolicy(Sandbox* sandbox, int sysno, void* aux) { |
| 709 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux); | 723 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux); |
| 710 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 724 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 711 return ErrorCode(ENOSYS); | 725 return ErrorCode(ENOSYS); |
| 712 } | 726 } |
| 713 | 727 |
| 714 switch (sysno) { | 728 switch (sysno) { |
| 715 case __NR_access: | 729 case __NR_access: |
| 716 case __NR_open: | 730 case __NR_open: |
| 717 case __NR_openat: | 731 case __NR_openat: |
| 718 // We get a InitializedOpenBroker class, but our trap handler wants | 732 // We get a InitializedOpenBroker class, but our trap handler wants |
| 719 // the BrokerProcess object. | 733 // the BrokerProcess object. |
| 720 return ErrorCode(sandbox->Trap(BrokerOpenTrapHandler, | 734 return ErrorCode( |
| 721 iob->broker_process())); | 735 sandbox->Trap(BrokerOpenTrapHandler, iob->broker_process())); |
| 722 default: | 736 default: |
| 723 return ErrorCode(ErrorCode::ERR_ALLOWED); | 737 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 724 } | 738 } |
| 725 } | 739 } |
| 726 | 740 |
| 727 // We use a InitializedOpenBroker class, so that we can run unsandboxed | 741 // We use a InitializedOpenBroker class, so that we can run unsandboxed |
| 728 // code in its constructor, which is the only way to do so in a BPF_TEST. | 742 // code in its constructor, which is the only way to do so in a BPF_TEST. |
| 729 BPF_TEST(SandboxBpf, UseOpenBroker, DenyOpenPolicy, | 743 BPF_TEST(SandboxBpf, |
| 744 UseOpenBroker, |
| 745 DenyOpenPolicy, |
| 730 InitializedOpenBroker /* BPF_AUX */) { | 746 InitializedOpenBroker /* BPF_AUX */) { |
| 731 BPF_ASSERT(BPF_AUX.initialized()); | 747 BPF_ASSERT(BPF_AUX.initialized()); |
| 732 BrokerProcess* broker_process = BPF_AUX.broker_process(); | 748 BrokerProcess* broker_process = BPF_AUX.broker_process(); |
| 733 BPF_ASSERT(broker_process != NULL); | 749 BPF_ASSERT(broker_process != NULL); |
| 734 | 750 |
| 735 // First, use the broker "manually" | 751 // First, use the broker "manually" |
| 736 BPF_ASSERT(broker_process->Open("/proc/denied", O_RDONLY) == -EPERM); | 752 BPF_ASSERT(broker_process->Open("/proc/denied", O_RDONLY) == -EPERM); |
| 737 BPF_ASSERT(broker_process->Access("/proc/denied", R_OK) == -EPERM); | 753 BPF_ASSERT(broker_process->Access("/proc/denied", R_OK) == -EPERM); |
| 738 BPF_ASSERT(broker_process->Open("/proc/allowed", O_RDONLY) == -ENOENT); | 754 BPF_ASSERT(broker_process->Open("/proc/allowed", O_RDONLY) == -ENOENT); |
| 739 BPF_ASSERT(broker_process->Access("/proc/allowed", R_OK) == -ENOENT); | 755 BPF_ASSERT(broker_process->Access("/proc/allowed", R_OK) == -ENOENT); |
| 740 | 756 |
| 741 // Now use glibc's open() as an external library would. | 757 // Now use glibc's open() as an external library would. |
| 742 BPF_ASSERT(open("/proc/denied", O_RDONLY) == -1); | 758 BPF_ASSERT(open("/proc/denied", O_RDONLY) == -1); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 764 int cpu_info_access = access("/proc/cpuinfo", R_OK); | 780 int cpu_info_access = access("/proc/cpuinfo", R_OK); |
| 765 BPF_ASSERT(cpu_info_access == 0); | 781 BPF_ASSERT(cpu_info_access == 0); |
| 766 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); | 782 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); |
| 767 BPF_ASSERT(cpu_info_fd >= 0); | 783 BPF_ASSERT(cpu_info_fd >= 0); |
| 768 char buf[1024]; | 784 char buf[1024]; |
| 769 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); | 785 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); |
| 770 } | 786 } |
| 771 | 787 |
| 772 // Simple test demonstrating how to use Sandbox::Cond() | 788 // Simple test demonstrating how to use Sandbox::Cond() |
| 773 | 789 |
| 774 ErrorCode SimpleCondTestPolicy(Sandbox *sandbox, int sysno, void *) { | 790 ErrorCode SimpleCondTestPolicy(Sandbox* sandbox, int sysno, void*) { |
| 775 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 791 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 776 // FIXME: we should really not have to do that in a trivial policy | 792 // FIXME: we should really not have to do that in a trivial policy |
| 777 return ErrorCode(ENOSYS); | 793 return ErrorCode(ENOSYS); |
| 778 } | 794 } |
| 779 | 795 |
| 780 // We deliberately return unusual errno values upon failure, so that we | 796 // We deliberately return unusual errno values upon failure, so that we |
| 781 // can uniquely test for these values. In a "real" policy, you would want | 797 // can uniquely test for these values. In a "real" policy, you would want |
| 782 // to return more traditional values. | 798 // to return more traditional values. |
| 783 switch (sysno) { | 799 switch (sysno) { |
| 784 case __NR_open: | 800 case __NR_open: |
| 785 // Allow opening files for reading, but don't allow writing. | 801 // Allow opening files for reading, but don't allow writing. |
| 786 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); | 802 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); |
| 787 return sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 803 return sandbox->Cond(1, |
| 804 ErrorCode::TP_32BIT, |
| 805 ErrorCode::OP_HAS_ANY_BITS, |
| 788 O_ACCMODE /* 0x3 */, | 806 O_ACCMODE /* 0x3 */, |
| 789 ErrorCode(EROFS), | 807 ErrorCode(EROFS), |
| 790 ErrorCode(ErrorCode::ERR_ALLOWED)); | 808 ErrorCode(ErrorCode::ERR_ALLOWED)); |
| 791 case __NR_prctl: | 809 case __NR_prctl: |
| 792 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but | 810 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but |
| 793 // disallow everything else. | 811 // disallow everything else. |
| 794 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 812 return sandbox->Cond(0, |
| 813 ErrorCode::TP_32BIT, |
| 814 ErrorCode::OP_EQUAL, |
| 795 PR_SET_DUMPABLE, | 815 PR_SET_DUMPABLE, |
| 796 ErrorCode(ErrorCode::ERR_ALLOWED), | 816 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 797 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 817 sandbox->Cond(0, |
| 798 PR_GET_DUMPABLE, | 818 ErrorCode::TP_32BIT, |
| 799 ErrorCode(ErrorCode::ERR_ALLOWED), | 819 ErrorCode::OP_EQUAL, |
| 800 ErrorCode(ENOMEM))); | 820 PR_GET_DUMPABLE, |
| 821 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 822 ErrorCode(ENOMEM))); |
| 801 default: | 823 default: |
| 802 return ErrorCode(ErrorCode::ERR_ALLOWED); | 824 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 803 } | 825 } |
| 804 } | 826 } |
| 805 | 827 |
| 806 BPF_TEST(SandboxBpf, SimpleCondTest, SimpleCondTestPolicy) { | 828 BPF_TEST(SandboxBpf, SimpleCondTest, SimpleCondTestPolicy) { |
| 807 int fd; | 829 int fd; |
| 808 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); | 830 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); |
| 809 BPF_ASSERT(errno == EROFS); | 831 BPF_ASSERT(errno == EROFS); |
| 810 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); | 832 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); |
| 811 close(fd); | 833 close(fd); |
| 812 | 834 |
| 813 int ret; | 835 int ret; |
| 814 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); | 836 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); |
| 815 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1-ret) == 0); | 837 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0); |
| 816 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); | 838 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); |
| 817 BPF_ASSERT(errno == ENOMEM); | 839 BPF_ASSERT(errno == ENOMEM); |
| 818 } | 840 } |
| 819 | 841 |
| 820 // This test exercises the Sandbox::Cond() method by building a complex | 842 // This test exercises the Sandbox::Cond() method by building a complex |
| 821 // tree of conditional equality operations. It then makes system calls and | 843 // tree of conditional equality operations. It then makes system calls and |
| 822 // verifies that they return the values that we expected from our BPF | 844 // verifies that they return the values that we expected from our BPF |
| 823 // program. | 845 // program. |
| 824 class EqualityStressTest { | 846 class EqualityStressTest { |
| 825 public: | 847 public: |
| 826 EqualityStressTest() { | 848 EqualityStressTest() { |
| 827 // We want a deterministic test | 849 // We want a deterministic test |
| 828 srand(0); | 850 srand(0); |
| 829 | 851 |
| 830 // Iterates over system call numbers and builds a random tree of | 852 // Iterates over system call numbers and builds a random tree of |
| 831 // equality tests. | 853 // equality tests. |
| 832 // We are actually constructing a graph of ArgValue objects. This | 854 // We are actually constructing a graph of ArgValue objects. This |
| 833 // graph will later be used to a) compute our sandbox policy, and | 855 // graph will later be used to a) compute our sandbox policy, and |
| 834 // b) drive the code that verifies the output from the BPF program. | 856 // b) drive the code that verifies the output from the BPF program. |
| 835 COMPILE_ASSERT(kNumTestCases < (int)(MAX_PUBLIC_SYSCALL-MIN_SYSCALL-10), | 857 COMPILE_ASSERT( |
| 836 num_test_cases_must_be_significantly_smaller_than_num_system_calls); | 858 kNumTestCases < (int)(MAX_PUBLIC_SYSCALL - MIN_SYSCALL - 10), |
| 859 num_test_cases_must_be_significantly_smaller_than_num_system_calls); |
| 837 for (int sysno = MIN_SYSCALL, end = kNumTestCases; sysno < end; ++sysno) { | 860 for (int sysno = MIN_SYSCALL, end = kNumTestCases; sysno < end; ++sysno) { |
| 838 if (IsReservedSyscall(sysno)) { | 861 if (IsReservedSyscall(sysno)) { |
| 839 // Skip reserved system calls. This ensures that our test frame | 862 // Skip reserved system calls. This ensures that our test frame |
| 840 // work isn't impacted by the fact that we are overriding | 863 // work isn't impacted by the fact that we are overriding |
| 841 // a lot of different system calls. | 864 // a lot of different system calls. |
| 842 ++end; | 865 ++end; |
| 843 arg_values_.push_back(NULL); | 866 arg_values_.push_back(NULL); |
| 844 } else { | 867 } else { |
| 845 arg_values_.push_back(RandomArgValue(rand() % kMaxArgs, 0, | 868 arg_values_.push_back( |
| 846 rand() % kMaxArgs)); | 869 RandomArgValue(rand() % kMaxArgs, 0, rand() % kMaxArgs)); |
| 847 } | 870 } |
| 848 } | 871 } |
| 849 } | 872 } |
| 850 | 873 |
| 851 ~EqualityStressTest() { | 874 ~EqualityStressTest() { |
| 852 for (std::vector<ArgValue *>::iterator iter = arg_values_.begin(); | 875 for (std::vector<ArgValue*>::iterator iter = arg_values_.begin(); |
| 853 iter != arg_values_.end(); | 876 iter != arg_values_.end(); |
| 854 ++iter) { | 877 ++iter) { |
| 855 DeleteArgValue(*iter); | 878 DeleteArgValue(*iter); |
| 856 } | 879 } |
| 857 } | 880 } |
| 858 | 881 |
| 859 ErrorCode Policy(Sandbox *sandbox, int sysno) { | 882 ErrorCode Policy(Sandbox* sandbox, int sysno) { |
| 860 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 883 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 861 // FIXME: we should really not have to do that in a trivial policy | 884 // FIXME: we should really not have to do that in a trivial policy |
| 862 return ErrorCode(ENOSYS); | 885 return ErrorCode(ENOSYS); |
| 863 } else if (sysno < 0 || sysno >= (int)arg_values_.size() || | 886 } else if (sysno < 0 || sysno >= (int)arg_values_.size() || |
| 864 IsReservedSyscall(sysno)) { | 887 IsReservedSyscall(sysno)) { |
| 865 // We only return ErrorCode values for the system calls that | 888 // We only return ErrorCode values for the system calls that |
| 866 // are part of our test data. Every other system call remains | 889 // are part of our test data. Every other system call remains |
| 867 // allowed. | 890 // allowed. |
| 868 return ErrorCode(ErrorCode::ERR_ALLOWED); | 891 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 869 } else { | 892 } else { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 881 // Skip reserved system calls. | 904 // Skip reserved system calls. |
| 882 continue; | 905 continue; |
| 883 } | 906 } |
| 884 // Verify that system calls return the values that we expect them to | 907 // Verify that system calls return the values that we expect them to |
| 885 // return. This involves passing different combinations of system call | 908 // return. This involves passing different combinations of system call |
| 886 // parameters in order to exercise all possible code paths through the | 909 // parameters in order to exercise all possible code paths through the |
| 887 // BPF filter program. | 910 // BPF filter program. |
| 888 // We arbitrarily start by setting all six system call arguments to | 911 // We arbitrarily start by setting all six system call arguments to |
| 889 // zero. And we then recursive traverse our tree of ArgValues to | 912 // zero. And we then recursive traverse our tree of ArgValues to |
| 890 // determine the necessary combinations of parameters. | 913 // determine the necessary combinations of parameters. |
| 891 intptr_t args[6] = { }; | 914 intptr_t args[6] = {}; |
| 892 Verify(sysno, args, *arg_values_[sysno]); | 915 Verify(sysno, args, *arg_values_[sysno]); |
| 893 } | 916 } |
| 894 } | 917 } |
| 895 | 918 |
| 896 private: | 919 private: |
| 897 struct ArgValue { | 920 struct ArgValue { |
| 898 int argno; // Argument number to inspect. | 921 int argno; // Argument number to inspect. |
| 899 int size; // Number of test cases (must be > 0). | 922 int size; // Number of test cases (must be > 0). |
| 900 struct Tests { | 923 struct Tests { |
| 901 uint32_t k_value; // Value to compare syscall arg against. | 924 uint32_t k_value; // Value to compare syscall arg against. |
| 902 int err; // If non-zero, errno value to return. | 925 int err; // If non-zero, errno value to return. |
| 903 struct ArgValue *arg_value; // Otherwise, more args needs inspecting. | 926 struct ArgValue* arg_value; // Otherwise, more args needs inspecting. |
| 904 } *tests; | 927 }* tests; |
| 905 int err; // If none of the tests passed, this is what | 928 int err; // If none of the tests passed, this is what |
| 906 struct ArgValue *arg_value; // we'll return (this is the "else" branch). | 929 struct ArgValue* arg_value; // we'll return (this is the "else" branch). |
| 907 }; | 930 }; |
| 908 | 931 |
| 909 bool IsReservedSyscall(int sysno) { | 932 bool IsReservedSyscall(int sysno) { |
| 910 // There are a handful of system calls that we should never use in our | 933 // There are a handful of system calls that we should never use in our |
| 911 // test cases. These system calls are needed to allow the test framework | 934 // test cases. These system calls are needed to allow the test framework |
| 912 // to run properly. | 935 // to run properly. |
| 913 // If we wanted to write fully generic code, there are more system calls | 936 // If we wanted to write fully generic code, there are more system calls |
| 914 // that could be listed here, and it is quite difficult to come up with a | 937 // that could be listed here, and it is quite difficult to come up with a |
| 915 // truly comprehensive list. After all, we are deliberately making system | 938 // truly comprehensive list. After all, we are deliberately making system |
| 916 // calls unavailable. In practice, we have a pretty good idea of the system | 939 // calls unavailable. In practice, we have a pretty good idea of the system |
| 917 // calls that will be made by this particular test. So, this small list is | 940 // calls that will be made by this particular test. So, this small list is |
| 918 // sufficient. But if anybody copy'n'pasted this code for other uses, they | 941 // sufficient. But if anybody copy'n'pasted this code for other uses, they |
| 919 // would have to review that the list. | 942 // would have to review that the list. |
| 920 return sysno == __NR_read || | 943 return sysno == __NR_read || sysno == __NR_write || sysno == __NR_exit || |
| 921 sysno == __NR_write || | 944 sysno == __NR_exit_group || sysno == __NR_restart_syscall; |
| 922 sysno == __NR_exit || | |
| 923 sysno == __NR_exit_group || | |
| 924 sysno == __NR_restart_syscall; | |
| 925 } | 945 } |
| 926 | 946 |
| 927 ArgValue *RandomArgValue(int argno, int args_mask, int remaining_args) { | 947 ArgValue* RandomArgValue(int argno, int args_mask, int remaining_args) { |
| 928 // Create a new ArgValue and fill it with random data. We use as bit mask | 948 // Create a new ArgValue and fill it with random data. We use as bit mask |
| 929 // to keep track of the system call parameters that have previously been | 949 // to keep track of the system call parameters that have previously been |
| 930 // set; this ensures that we won't accidentally define a contradictory | 950 // set; this ensures that we won't accidentally define a contradictory |
| 931 // set of equality tests. | 951 // set of equality tests. |
| 932 struct ArgValue *arg_value = new ArgValue(); | 952 struct ArgValue* arg_value = new ArgValue(); |
| 933 args_mask |= 1 << argno; | 953 args_mask |= 1 << argno; |
| 934 arg_value->argno = argno; | 954 arg_value->argno = argno; |
| 935 | 955 |
| 936 // Apply some restrictions on just how complex our tests can be. | 956 // Apply some restrictions on just how complex our tests can be. |
| 937 // Otherwise, we end up with a BPF program that is too complicated for | 957 // Otherwise, we end up with a BPF program that is too complicated for |
| 938 // the kernel to load. | 958 // the kernel to load. |
| 939 int fan_out = kMaxFanOut; | 959 int fan_out = kMaxFanOut; |
| 940 if (remaining_args > 3) { | 960 if (remaining_args > 3) { |
| 941 fan_out = 1; | 961 fan_out = 1; |
| 942 } else if (remaining_args > 2) { | 962 } else if (remaining_args > 2) { |
| 943 fan_out = 2; | 963 fan_out = 2; |
| 944 } | 964 } |
| 945 | 965 |
| 946 // Create a couple of different test cases with randomized values that | 966 // Create a couple of different test cases with randomized values that |
| 947 // we want to use when comparing system call parameter number "argno". | 967 // we want to use when comparing system call parameter number "argno". |
| 948 arg_value->size = rand() % fan_out + 1; | 968 arg_value->size = rand() % fan_out + 1; |
| 949 arg_value->tests = new ArgValue::Tests[arg_value->size]; | 969 arg_value->tests = new ArgValue::Tests[arg_value->size]; |
| 950 | 970 |
| 951 uint32_t k_value = rand(); | 971 uint32_t k_value = rand(); |
| 952 for (int n = 0; n < arg_value->size; ++n) { | 972 for (int n = 0; n < arg_value->size; ++n) { |
| 953 // Ensure that we have unique values | 973 // Ensure that we have unique values |
| 954 k_value += rand() % (RAND_MAX/(kMaxFanOut+1)) + 1; | 974 k_value += rand() % (RAND_MAX / (kMaxFanOut + 1)) + 1; |
| 955 | 975 |
| 956 // There are two possible types of nodes. Either this is a leaf node; | 976 // There are two possible types of nodes. Either this is a leaf node; |
| 957 // in that case, we have completed all the equality tests that we | 977 // in that case, we have completed all the equality tests that we |
| 958 // wanted to perform, and we can now compute a random "errno" value that | 978 // wanted to perform, and we can now compute a random "errno" value that |
| 959 // we should return. Or this is part of a more complex boolean | 979 // we should return. Or this is part of a more complex boolean |
| 960 // expression; in that case, we have to recursively add tests for some | 980 // expression; in that case, we have to recursively add tests for some |
| 961 // of system call parameters that we have not yet included in our | 981 // of system call parameters that we have not yet included in our |
| 962 // tests. | 982 // tests. |
| 963 arg_value->tests[n].k_value = k_value; | 983 arg_value->tests[n].k_value = k_value; |
| 964 if (!remaining_args || (rand() & 1)) { | 984 if (!remaining_args || (rand() & 1)) { |
| 965 arg_value->tests[n].err = (rand() % 1000) + 1; | 985 arg_value->tests[n].err = (rand() % 1000) + 1; |
| 966 arg_value->tests[n].arg_value = NULL; | 986 arg_value->tests[n].arg_value = NULL; |
| 967 } else { | 987 } else { |
| 968 arg_value->tests[n].err = 0; | 988 arg_value->tests[n].err = 0; |
| 969 arg_value->tests[n].arg_value = | 989 arg_value->tests[n].arg_value = |
| 970 RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1); | 990 RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1); |
| 971 } | 991 } |
| 972 } | 992 } |
| 973 // Finally, we have to define what we should return if none of the | 993 // Finally, we have to define what we should return if none of the |
| 974 // previous equality tests pass. Again, we can either deal with a leaf | 994 // previous equality tests pass. Again, we can either deal with a leaf |
| 975 // node, or we can randomly add another couple of tests. | 995 // node, or we can randomly add another couple of tests. |
| 976 if (!remaining_args || (rand() & 1)) { | 996 if (!remaining_args || (rand() & 1)) { |
| 977 arg_value->err = (rand() % 1000) + 1; | 997 arg_value->err = (rand() % 1000) + 1; |
| 978 arg_value->arg_value = NULL; | 998 arg_value->arg_value = NULL; |
| 979 } else { | 999 } else { |
| 980 arg_value->err = 0; | 1000 arg_value->err = 0; |
| 981 arg_value->arg_value = | 1001 arg_value->arg_value = |
| 982 RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1); | 1002 RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1); |
| 983 } | 1003 } |
| 984 // We have now built a new (sub-)tree of ArgValues defining a set of | 1004 // We have now built a new (sub-)tree of ArgValues defining a set of |
| 985 // boolean expressions for testing random system call arguments against | 1005 // boolean expressions for testing random system call arguments against |
| 986 // random values. Return this tree to our caller. | 1006 // random values. Return this tree to our caller. |
| 987 return arg_value; | 1007 return arg_value; |
| 988 } | 1008 } |
| 989 | 1009 |
| 990 int RandomArg(int args_mask) { | 1010 int RandomArg(int args_mask) { |
| 991 // Compute a random system call parameter number. | 1011 // Compute a random system call parameter number. |
| 992 int argno = rand() % kMaxArgs; | 1012 int argno = rand() % kMaxArgs; |
| 993 | 1013 |
| 994 // Make sure that this same parameter number has not previously been | 1014 // Make sure that this same parameter number has not previously been |
| 995 // used. Otherwise, we could end up with a test that is impossible to | 1015 // used. Otherwise, we could end up with a test that is impossible to |
| 996 // satisfy (e.g. args[0] == 1 && args[0] == 2). | 1016 // satisfy (e.g. args[0] == 1 && args[0] == 2). |
| 997 while (args_mask & (1 << argno)) { | 1017 while (args_mask & (1 << argno)) { |
| 998 argno = (argno + 1) % kMaxArgs; | 1018 argno = (argno + 1) % kMaxArgs; |
| 999 } | 1019 } |
| 1000 return argno; | 1020 return argno; |
| 1001 } | 1021 } |
| 1002 | 1022 |
| 1003 void DeleteArgValue(ArgValue *arg_value) { | 1023 void DeleteArgValue(ArgValue* arg_value) { |
| 1004 // Delete an ArgValue and all of its child nodes. This requires | 1024 // Delete an ArgValue and all of its child nodes. This requires |
| 1005 // recursively descending into the tree. | 1025 // recursively descending into the tree. |
| 1006 if (arg_value) { | 1026 if (arg_value) { |
| 1007 if (arg_value->size) { | 1027 if (arg_value->size) { |
| 1008 for (int n = 0; n < arg_value->size; ++n) { | 1028 for (int n = 0; n < arg_value->size; ++n) { |
| 1009 if (!arg_value->tests[n].err) { | 1029 if (!arg_value->tests[n].err) { |
| 1010 DeleteArgValue(arg_value->tests[n].arg_value); | 1030 DeleteArgValue(arg_value->tests[n].arg_value); |
| 1011 } | 1031 } |
| 1012 } | 1032 } |
| 1013 delete[] arg_value->tests; | 1033 delete[] arg_value->tests; |
| 1014 } | 1034 } |
| 1015 if (!arg_value->err) { | 1035 if (!arg_value->err) { |
| 1016 DeleteArgValue(arg_value->arg_value); | 1036 DeleteArgValue(arg_value->arg_value); |
| 1017 } | 1037 } |
| 1018 delete arg_value; | 1038 delete arg_value; |
| 1019 } | 1039 } |
| 1020 } | 1040 } |
| 1021 | 1041 |
| 1022 ErrorCode ToErrorCode(Sandbox *sandbox, ArgValue *arg_value) { | 1042 ErrorCode ToErrorCode(Sandbox* sandbox, ArgValue* arg_value) { |
| 1023 // Compute the ErrorCode that should be returned, if none of our | 1043 // Compute the ErrorCode that should be returned, if none of our |
| 1024 // tests succeed (i.e. the system call parameter doesn't match any | 1044 // tests succeed (i.e. the system call parameter doesn't match any |
| 1025 // of the values in arg_value->tests[].k_value). | 1045 // of the values in arg_value->tests[].k_value). |
| 1026 ErrorCode err; | 1046 ErrorCode err; |
| 1027 if (arg_value->err) { | 1047 if (arg_value->err) { |
| 1028 // If this was a leaf node, return the errno value that we expect to | 1048 // If this was a leaf node, return the errno value that we expect to |
| 1029 // return from the BPF filter program. | 1049 // return from the BPF filter program. |
| 1030 err = ErrorCode(arg_value->err); | 1050 err = ErrorCode(arg_value->err); |
| 1031 } else { | 1051 } else { |
| 1032 // If this wasn't a leaf node yet, recursively descend into the rest | 1052 // If this wasn't a leaf node yet, recursively descend into the rest |
| 1033 // of the tree. This will end up adding a few more Sandbox::Cond() | 1053 // of the tree. This will end up adding a few more Sandbox::Cond() |
| 1034 // tests to our ErrorCode. | 1054 // tests to our ErrorCode. |
| 1035 err = ToErrorCode(sandbox, arg_value->arg_value); | 1055 err = ToErrorCode(sandbox, arg_value->arg_value); |
| 1036 } | 1056 } |
| 1037 | 1057 |
| 1038 // Now, iterate over all the test cases that we want to compare against. | 1058 // Now, iterate over all the test cases that we want to compare against. |
| 1039 // This builds a chain of Sandbox::Cond() tests | 1059 // This builds a chain of Sandbox::Cond() tests |
| 1040 // (aka "if ... elif ... elif ... elif ... fi") | 1060 // (aka "if ... elif ... elif ... elif ... fi") |
| 1041 for (int n = arg_value->size; n-- > 0; ) { | 1061 for (int n = arg_value->size; n-- > 0;) { |
| 1042 ErrorCode matched; | 1062 ErrorCode matched; |
| 1043 // Again, we distinguish between leaf nodes and subtrees. | 1063 // Again, we distinguish between leaf nodes and subtrees. |
| 1044 if (arg_value->tests[n].err) { | 1064 if (arg_value->tests[n].err) { |
| 1045 matched = ErrorCode(arg_value->tests[n].err); | 1065 matched = ErrorCode(arg_value->tests[n].err); |
| 1046 } else { | 1066 } else { |
| 1047 matched = ToErrorCode(sandbox, arg_value->tests[n].arg_value); | 1067 matched = ToErrorCode(sandbox, arg_value->tests[n].arg_value); |
| 1048 } | 1068 } |
| 1049 // For now, all of our tests are limited to 32bit. | 1069 // For now, all of our tests are limited to 32bit. |
| 1050 // We have separate tests that check the behavior of 32bit vs. 64bit | 1070 // We have separate tests that check the behavior of 32bit vs. 64bit |
| 1051 // conditional expressions. | 1071 // conditional expressions. |
| 1052 err = sandbox->Cond(arg_value->argno, ErrorCode::TP_32BIT, | 1072 err = sandbox->Cond(arg_value->argno, |
| 1053 ErrorCode::OP_EQUAL, arg_value->tests[n].k_value, | 1073 ErrorCode::TP_32BIT, |
| 1054 matched, err); | 1074 ErrorCode::OP_EQUAL, |
| 1075 arg_value->tests[n].k_value, |
| 1076 matched, |
| 1077 err); |
| 1055 } | 1078 } |
| 1056 return err; | 1079 return err; |
| 1057 } | 1080 } |
| 1058 | 1081 |
| 1059 void Verify(int sysno, intptr_t *args, const ArgValue& arg_value) { | 1082 void Verify(int sysno, intptr_t* args, const ArgValue& arg_value) { |
| 1060 uint32_t mismatched = 0; | 1083 uint32_t mismatched = 0; |
| 1061 // Iterate over all the k_values in arg_value.tests[] and verify that | 1084 // Iterate over all the k_values in arg_value.tests[] and verify that |
| 1062 // we see the expected return values from system calls, when we pass | 1085 // we see the expected return values from system calls, when we pass |
| 1063 // the k_value as a parameter in a system call. | 1086 // the k_value as a parameter in a system call. |
| 1064 for (int n = arg_value.size; n-- > 0; ) { | 1087 for (int n = arg_value.size; n-- > 0;) { |
| 1065 mismatched += arg_value.tests[n].k_value; | 1088 mismatched += arg_value.tests[n].k_value; |
| 1066 args[arg_value.argno] = arg_value.tests[n].k_value; | 1089 args[arg_value.argno] = arg_value.tests[n].k_value; |
| 1067 if (arg_value.tests[n].err) { | 1090 if (arg_value.tests[n].err) { |
| 1068 VerifyErrno(sysno, args, arg_value.tests[n].err); | 1091 VerifyErrno(sysno, args, arg_value.tests[n].err); |
| 1069 } else { | 1092 } else { |
| 1070 Verify(sysno, args, *arg_value.tests[n].arg_value); | 1093 Verify(sysno, args, *arg_value.tests[n].arg_value); |
| 1071 } | 1094 } |
| 1072 } | 1095 } |
| 1073 // Find a k_value that doesn't match any of the k_values in | 1096 // Find a k_value that doesn't match any of the k_values in |
| 1074 // arg_value.tests[]. In most cases, the current value of "mismatched" | 1097 // arg_value.tests[]. In most cases, the current value of "mismatched" |
| 1075 // would fit this requirement. But on the off-chance that it happens | 1098 // would fit this requirement. But on the off-chance that it happens |
| 1076 // to collide, we double-check. | 1099 // to collide, we double-check. |
| 1077 try_again: | 1100 try_again: |
| 1078 for (int n = arg_value.size; n-- > 0; ) { | 1101 for (int n = arg_value.size; n-- > 0;) { |
| 1079 if (mismatched == arg_value.tests[n].k_value) { | 1102 if (mismatched == arg_value.tests[n].k_value) { |
| 1080 ++mismatched; | 1103 ++mismatched; |
| 1081 goto try_again; | 1104 goto try_again; |
| 1082 } | 1105 } |
| 1083 } | 1106 } |
| 1084 // Now verify that we see the expected return value from system calls, | 1107 // Now verify that we see the expected return value from system calls, |
| 1085 // if we pass a value that doesn't match any of the conditions (i.e. this | 1108 // if we pass a value that doesn't match any of the conditions (i.e. this |
| 1086 // is testing the "else" clause of the conditions). | 1109 // is testing the "else" clause of the conditions). |
| 1087 args[arg_value.argno] = mismatched; | 1110 args[arg_value.argno] = mismatched; |
| 1088 if (arg_value.err) { | 1111 if (arg_value.err) { |
| 1089 VerifyErrno(sysno, args, arg_value.err); | 1112 VerifyErrno(sysno, args, arg_value.err); |
| 1090 } else { | 1113 } else { |
| 1091 Verify(sysno, args, *arg_value.arg_value); | 1114 Verify(sysno, args, *arg_value.arg_value); |
| 1092 } | 1115 } |
| 1093 // Reset args[arg_value.argno]. This is not technically needed, but it | 1116 // Reset args[arg_value.argno]. This is not technically needed, but it |
| 1094 // makes it easier to reason about the correctness of our tests. | 1117 // makes it easier to reason about the correctness of our tests. |
| 1095 args[arg_value.argno] = 0; | 1118 args[arg_value.argno] = 0; |
| 1096 } | 1119 } |
| 1097 | 1120 |
| 1098 void VerifyErrno(int sysno, intptr_t *args, int err) { | 1121 void VerifyErrno(int sysno, intptr_t* args, int err) { |
| 1099 // We installed BPF filters that return different errno values | 1122 // We installed BPF filters that return different errno values |
| 1100 // based on the system call number and the parameters that we decided | 1123 // based on the system call number and the parameters that we decided |
| 1101 // to pass in. Verify that this condition holds true. | 1124 // to pass in. Verify that this condition holds true. |
| 1102 BPF_ASSERT(SandboxSyscall(sysno, | 1125 BPF_ASSERT( |
| 1103 args[0], args[1], args[2], | 1126 SandboxSyscall( |
| 1104 args[3], args[4], args[5]) == -err); | 1127 sysno, args[0], args[1], args[2], args[3], args[4], args[5]) == |
| 1128 -err); |
| 1105 } | 1129 } |
| 1106 | 1130 |
| 1107 // Vector of ArgValue trees. These trees define all the possible boolean | 1131 // Vector of ArgValue trees. These trees define all the possible boolean |
| 1108 // expressions that we want to turn into a BPF filter program. | 1132 // expressions that we want to turn into a BPF filter program. |
| 1109 std::vector<ArgValue *> arg_values_; | 1133 std::vector<ArgValue*> arg_values_; |
| 1110 | 1134 |
| 1111 // Don't increase these values. We are pushing the limits of the maximum | 1135 // Don't increase these values. We are pushing the limits of the maximum |
| 1112 // BPF program that the kernel will allow us to load. If the values are | 1136 // BPF program that the kernel will allow us to load. If the values are |
| 1113 // increased too much, the test will start failing. | 1137 // increased too much, the test will start failing. |
| 1114 static const int kNumTestCases = 40; | 1138 static const int kNumTestCases = 40; |
| 1115 static const int kMaxFanOut = 3; | 1139 static const int kMaxFanOut = 3; |
| 1116 static const int kMaxArgs = 6; | 1140 static const int kMaxArgs = 6; |
| 1117 }; | 1141 }; |
| 1118 | 1142 |
| 1119 ErrorCode EqualityStressTestPolicy(Sandbox *sandbox, int sysno, void *aux) { | 1143 ErrorCode EqualityStressTestPolicy(Sandbox* sandbox, int sysno, void* aux) { |
| 1120 return reinterpret_cast<EqualityStressTest *>(aux)->Policy(sandbox, sysno); | 1144 return reinterpret_cast<EqualityStressTest*>(aux)->Policy(sandbox, sysno); |
| 1121 } | 1145 } |
| 1122 | 1146 |
| 1123 BPF_TEST(SandboxBpf, EqualityTests, EqualityStressTestPolicy, | 1147 BPF_TEST(SandboxBpf, |
| 1148 EqualityTests, |
| 1149 EqualityStressTestPolicy, |
| 1124 EqualityStressTest /* BPF_AUX */) { | 1150 EqualityStressTest /* BPF_AUX */) { |
| 1125 BPF_AUX.VerifyFilter(); | 1151 BPF_AUX.VerifyFilter(); |
| 1126 } | 1152 } |
| 1127 | 1153 |
| 1128 ErrorCode EqualityArgumentWidthPolicy(Sandbox *sandbox, int sysno, void *) { | 1154 ErrorCode EqualityArgumentWidthPolicy(Sandbox* sandbox, int sysno, void*) { |
| 1129 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1155 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1130 // FIXME: we should really not have to do that in a trivial policy | 1156 // FIXME: we should really not have to do that in a trivial policy |
| 1131 return ErrorCode(ENOSYS); | 1157 return ErrorCode(ENOSYS); |
| 1132 } else if (sysno == __NR_uname) { | 1158 } else if (sysno == __NR_uname) { |
| 1133 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1159 return sandbox->Cond( |
| 1134 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1160 0, |
| 1135 0x55555555, ErrorCode(1), ErrorCode(2)), | 1161 ErrorCode::TP_32BIT, |
| 1136 // The BPF compiler and the BPF interpreter in the kernel are | 1162 ErrorCode::OP_EQUAL, |
| 1137 // (mostly) agnostic of the host platform's word size. The compiler | 1163 0, |
| 1138 // will happily generate code that tests a 64bit value, and the | 1164 sandbox->Cond(1, |
| 1139 // interpreter will happily perform this test. | 1165 ErrorCode::TP_32BIT, |
| 1140 // But unless there is a kernel bug, there is no way for us to pass | 1166 ErrorCode::OP_EQUAL, |
| 1141 // in a 64bit quantity on a 32bit platform. The upper 32bits should | 1167 0x55555555, |
| 1142 // always be zero. So, this test should always evaluate as false on | 1168 ErrorCode(1), |
| 1143 // 32bit systems. | 1169 ErrorCode(2)), |
| 1144 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_EQUAL, | 1170 // The BPF compiler and the BPF interpreter in the kernel are |
| 1145 0x55555555AAAAAAAAULL, ErrorCode(1), ErrorCode(2))); | 1171 // (mostly) agnostic of the host platform's word size. The compiler |
| 1172 // will happily generate code that tests a 64bit value, and the |
| 1173 // interpreter will happily perform this test. |
| 1174 // But unless there is a kernel bug, there is no way for us to pass |
| 1175 // in a 64bit quantity on a 32bit platform. The upper 32bits should |
| 1176 // always be zero. So, this test should always evaluate as false on |
| 1177 // 32bit systems. |
| 1178 sandbox->Cond(1, |
| 1179 ErrorCode::TP_64BIT, |
| 1180 ErrorCode::OP_EQUAL, |
| 1181 0x55555555AAAAAAAAULL, |
| 1182 ErrorCode(1), |
| 1183 ErrorCode(2))); |
| 1146 } else { | 1184 } else { |
| 1147 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1185 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1148 } | 1186 } |
| 1149 } | 1187 } |
| 1150 | 1188 |
| 1151 BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { | 1189 BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { |
| 1152 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); | 1190 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); |
| 1153 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); | 1191 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); |
| 1154 #if __SIZEOF_POINTER__ > 4 | 1192 #if __SIZEOF_POINTER__ > 4 |
| 1155 // On 32bit machines, there is no way to pass a 64bit argument through the | 1193 // On 32bit machines, there is no way to pass a 64bit argument through the |
| 1156 // syscall interface. So, we have to skip the part of the test that requires | 1194 // syscall interface. So, we have to skip the part of the test that requires |
| 1157 // 64bit arguments. | 1195 // 64bit arguments. |
| 1158 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); | 1196 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); |
| 1159 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); | 1197 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); |
| 1160 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); | 1198 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); |
| 1161 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); | 1199 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); |
| 1162 #else | 1200 #else |
| 1163 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); | 1201 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); |
| 1164 #endif | 1202 #endif |
| 1165 } | 1203 } |
| 1166 | 1204 |
| 1167 #if __SIZEOF_POINTER__ > 4 | 1205 #if __SIZEOF_POINTER__ > 4 |
| 1168 // On 32bit machines, there is no way to pass a 64bit argument through the | 1206 // On 32bit machines, there is no way to pass a 64bit argument through the |
| 1169 // syscall interface. So, we have to skip the part of the test that requires | 1207 // syscall interface. So, we have to skip the part of the test that requires |
| 1170 // 64bit arguments. | 1208 // 64bit arguments. |
| 1171 BPF_DEATH_TEST(SandboxBpf, EqualityArgumentUnallowed64bit, | 1209 BPF_DEATH_TEST(SandboxBpf, |
| 1210 EqualityArgumentUnallowed64bit, |
| 1172 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1211 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
| 1173 EqualityArgumentWidthPolicy) { | 1212 EqualityArgumentWidthPolicy) { |
| 1174 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); | 1213 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); |
| 1175 } | 1214 } |
| 1176 #endif | 1215 #endif |
| 1177 | 1216 |
| 1178 ErrorCode EqualityWithNegativeArgumentsPolicy(Sandbox *sandbox, int sysno, | 1217 ErrorCode EqualityWithNegativeArgumentsPolicy(Sandbox* sandbox, |
| 1179 void *) { | 1218 int sysno, |
| 1219 void*) { |
| 1180 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1220 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1181 // FIXME: we should really not have to do that in a trivial policy | 1221 // FIXME: we should really not have to do that in a trivial policy |
| 1182 return ErrorCode(ENOSYS); | 1222 return ErrorCode(ENOSYS); |
| 1183 } else if (sysno == __NR_uname) { | 1223 } else if (sysno == __NR_uname) { |
| 1184 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1224 return sandbox->Cond(0, |
| 1185 0xFFFFFFFF, ErrorCode(1), ErrorCode(2)); | 1225 ErrorCode::TP_32BIT, |
| 1226 ErrorCode::OP_EQUAL, |
| 1227 0xFFFFFFFF, |
| 1228 ErrorCode(1), |
| 1229 ErrorCode(2)); |
| 1186 } else { | 1230 } else { |
| 1187 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1231 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1188 } | 1232 } |
| 1189 } | 1233 } |
| 1190 | 1234 |
| 1191 BPF_TEST(SandboxBpf, EqualityWithNegativeArguments, | 1235 BPF_TEST(SandboxBpf, |
| 1236 EqualityWithNegativeArguments, |
| 1192 EqualityWithNegativeArgumentsPolicy) { | 1237 EqualityWithNegativeArgumentsPolicy) { |
| 1193 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); | 1238 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); |
| 1194 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); | 1239 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); |
| 1195 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); | 1240 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); |
| 1196 } | 1241 } |
| 1197 | 1242 |
| 1198 #if __SIZEOF_POINTER__ > 4 | 1243 #if __SIZEOF_POINTER__ > 4 |
| 1199 BPF_DEATH_TEST(SandboxBpf, EqualityWithNegative64bitArguments, | 1244 BPF_DEATH_TEST(SandboxBpf, |
| 1245 EqualityWithNegative64bitArguments, |
| 1200 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1246 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
| 1201 EqualityWithNegativeArgumentsPolicy) { | 1247 EqualityWithNegativeArgumentsPolicy) { |
| 1202 // When expecting a 32bit system call argument, we look at the MSB of the | 1248 // When expecting a 32bit system call argument, we look at the MSB of the |
| 1203 // 64bit value and allow both "0" and "-1". But the latter is allowed only | 1249 // 64bit value and allow both "0" and "-1". But the latter is allowed only |
| 1204 // iff the LSB was negative. So, this death test should error out. | 1250 // iff the LSB was negative. So, this death test should error out. |
| 1205 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); | 1251 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); |
| 1206 } | 1252 } |
| 1207 #endif | 1253 #endif |
| 1208 | |
| 1209 ErrorCode AllBitTestPolicy(Sandbox *sandbox, int sysno, void *) { | 1254 ErrorCode AllBitTestPolicy(Sandbox *sandbox, int sysno, void *) { |
| 1210 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of | 1255 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of |
| 1211 // different bitmasks. We try to find bitmasks that could conceivably | 1256 // different bitmasks. We try to find bitmasks that could conceivably |
| 1212 // touch corner cases. | 1257 // touch corner cases. |
| 1213 // For all of these tests, we override the uname(). We can make use with | 1258 // For all of these tests, we override the uname(). We can make use with |
| 1214 // a single system call number, as we use the first system call argument to | 1259 // a single system call number, as we use the first system call argument to |
| 1215 // select the different bit masks that we want to test against. | 1260 // select the different bit masks that we want to test against. |
| 1216 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1261 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1217 // FIXME: we should really not have to do that in a trivial policy | 1262 // FIXME: we should really not have to do that in a trivial policy |
| 1218 return ErrorCode(ENOSYS); | 1263 return ErrorCode(ENOSYS); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 } | 1322 } |
| 1278 } | 1323 } |
| 1279 | 1324 |
| 1280 // Define a macro that performs tests using our test policy. | 1325 // Define a macro that performs tests using our test policy. |
| 1281 // NOTE: Not all of the arguments in this macro are actually used! | 1326 // NOTE: Not all of the arguments in this macro are actually used! |
| 1282 // They are here just to serve as documentation of the conditions | 1327 // They are here just to serve as documentation of the conditions |
| 1283 // implemented in the test policy. | 1328 // implemented in the test policy. |
| 1284 // Most notably, "op" and "mask" are unused by the macro. If you want | 1329 // Most notably, "op" and "mask" are unused by the macro. If you want |
| 1285 // to make changes to these values, you will have to edit the | 1330 // to make changes to these values, you will have to edit the |
| 1286 // test policy instead. | 1331 // test policy instead. |
| 1287 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ | 1332 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ |
| 1288 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) | 1333 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) |
| 1289 | 1334 |
| 1290 // Our uname() system call returns ErrorCode(1) for success and | 1335 // Our uname() system call returns ErrorCode(1) for success and |
| 1291 // ErrorCode(0) for failure. SandboxSyscall() turns this into an | 1336 // ErrorCode(0) for failure. SandboxSyscall() turns this into an |
| 1292 // exit code of -1 or 0. | 1337 // exit code of -1 or 0. |
| 1293 #define EXPECT_FAILURE 0 | 1338 #define EXPECT_FAILURE 0 |
| 1294 #define EXPECT_SUCCESS -1 | 1339 #define EXPECT_SUCCESS -1 |
| 1295 | 1340 |
| 1296 // A couple of our tests behave differently on 32bit and 64bit systems, as | 1341 // A couple of our tests behave differently on 32bit and 64bit systems, as |
| 1297 // there is no way for a 32bit system call to pass in a 64bit system call | 1342 // there is no way for a 32bit system call to pass in a 64bit system call |
| 1298 // argument "arg". | 1343 // argument "arg". |
| 1299 // We expect these tests to succeed on 64bit systems, but to tail on 32bit | 1344 // We expect these tests to succeed on 64bit systems, but to tail on 32bit |
| 1300 // systems. | 1345 // systems. |
| 1301 #define EXPT64_SUCCESS \ | 1346 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) |
| 1302 (sizeof(void *) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) | |
| 1303 | |
| 1304 BPF_TEST(SandboxBpf, AllBitTests, AllBitTestPolicy) { | 1347 BPF_TEST(SandboxBpf, AllBitTests, AllBitTestPolicy) { |
| 1305 // 32bit test: all of 0x0 (should always be true) | 1348 // 32bit test: all of 0x0 (should always be true) |
| 1306 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); | 1349 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1307 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); | 1350 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1308 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); | 1351 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1309 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); | 1352 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1310 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); | 1353 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1311 | 1354 |
| 1312 // 32bit test: all of 0x1 | 1355 // 32bit test: all of 0x1 |
| 1313 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); | 1356 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1397 | 1440 |
| 1398 // 64bit test: all of 0x100000001 | 1441 // 64bit test: all of 0x100000001 |
| 1399 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1442 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1400 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1443 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1401 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1444 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1402 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1445 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
| 1403 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1446 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1404 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1447 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
| 1405 } | 1448 } |
| 1406 | 1449 |
| 1407 ErrorCode AnyBitTestPolicy(Sandbox *sandbox, int sysno, void *) { | 1450 ErrorCode AnyBitTestPolicy(Sandbox* sandbox, int sysno, void*) { |
| 1408 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of | 1451 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of |
| 1409 // different bitmasks. We try to find bitmasks that could conceivably | 1452 // different bitmasks. We try to find bitmasks that could conceivably |
| 1410 // touch corner cases. | 1453 // touch corner cases. |
| 1411 // For all of these tests, we override the uname(). We can make use with | 1454 // For all of these tests, we override the uname(). We can make use with |
| 1412 // a single system call number, as we use the first system call argument to | 1455 // a single system call number, as we use the first system call argument to |
| 1413 // select the different bit masks that we want to test against. | 1456 // select the different bit masks that we want to test against. |
| 1414 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1457 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1415 // FIXME: we should really not have to do that in a trivial policy | 1458 // FIXME: we should really not have to do that in a trivial policy |
| 1416 return ErrorCode(ENOSYS); | 1459 return ErrorCode(ENOSYS); |
| 1417 } else if (sysno == __NR_uname) { | 1460 } else if (sysno == __NR_uname) { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 | 1617 |
| 1575 // 64bit test: any of 0x100000001 | 1618 // 64bit test: any of 0x100000001 |
| 1576 BITMASK_TEST( 10, 0x000000000LL, ANYBITS64,0x100000001, EXPECT_FAILURE); | 1619 BITMASK_TEST( 10, 0x000000000LL, ANYBITS64,0x100000001, EXPECT_FAILURE); |
| 1577 BITMASK_TEST( 10, 0x000000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1620 BITMASK_TEST( 10, 0x000000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
| 1578 BITMASK_TEST( 10, 0x100000000LL, ANYBITS64,0x100000001, EXPT64_SUCCESS); | 1621 BITMASK_TEST( 10, 0x100000000LL, ANYBITS64,0x100000001, EXPT64_SUCCESS); |
| 1579 BITMASK_TEST( 10, 0x100000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1622 BITMASK_TEST( 10, 0x100000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
| 1580 BITMASK_TEST( 10, 0xFFFFFFFFU, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1623 BITMASK_TEST( 10, 0xFFFFFFFFU, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
| 1581 BITMASK_TEST( 10, -1L, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1624 BITMASK_TEST( 10, -1L, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
| 1582 } | 1625 } |
| 1583 | 1626 |
| 1584 intptr_t PthreadTrapHandler(const struct arch_seccomp_data& args, void *aux) { | 1627 intptr_t PthreadTrapHandler(const struct arch_seccomp_data& args, void* aux) { |
| 1585 if (args.args[0] != (CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD)) { | 1628 if (args.args[0] != (CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD)) { |
| 1586 // We expect to get called for an attempt to fork(). No need to log that | 1629 // We expect to get called for an attempt to fork(). No need to log that |
| 1587 // call. But if we ever get called for anything else, we want to verbosely | 1630 // call. But if we ever get called for anything else, we want to verbosely |
| 1588 // print as much information as possible. | 1631 // print as much information as possible. |
| 1589 const char *msg = (const char *)aux; | 1632 const char* msg = (const char*)aux; |
| 1590 printf("Clone() was called with unexpected arguments\n" | 1633 printf( |
| 1591 " nr: %d\n" | 1634 "Clone() was called with unexpected arguments\n" |
| 1592 " 1: 0x%llX\n" | 1635 " nr: %d\n" |
| 1593 " 2: 0x%llX\n" | 1636 " 1: 0x%llX\n" |
| 1594 " 3: 0x%llX\n" | 1637 " 2: 0x%llX\n" |
| 1595 " 4: 0x%llX\n" | 1638 " 3: 0x%llX\n" |
| 1596 " 5: 0x%llX\n" | 1639 " 4: 0x%llX\n" |
| 1597 " 6: 0x%llX\n" | 1640 " 5: 0x%llX\n" |
| 1598 "%s\n", | 1641 " 6: 0x%llX\n" |
| 1599 args.nr, | 1642 "%s\n", |
| 1600 (long long)args.args[0], (long long)args.args[1], | 1643 args.nr, |
| 1601 (long long)args.args[2], (long long)args.args[3], | 1644 (long long)args.args[0], |
| 1602 (long long)args.args[4], (long long)args.args[5], | 1645 (long long)args.args[1], |
| 1603 msg); | 1646 (long long)args.args[2], |
| 1647 (long long)args.args[3], |
| 1648 (long long)args.args[4], |
| 1649 (long long)args.args[5], |
| 1650 msg); |
| 1604 } | 1651 } |
| 1605 return -EPERM; | 1652 return -EPERM; |
| 1606 } | 1653 } |
| 1607 | 1654 ErrorCode PthreadPolicyEquality(Sandbox* sandbox, int sysno, void* aux) { |
| 1608 ErrorCode PthreadPolicyEquality(Sandbox *sandbox, int sysno, void *aux) { | |
| 1609 // This policy allows creating threads with pthread_create(). But it | 1655 // This policy allows creating threads with pthread_create(). But it |
| 1610 // doesn't allow any other uses of clone(). Most notably, it does not | 1656 // doesn't allow any other uses of clone(). Most notably, it does not |
| 1611 // allow callers to implement fork() or vfork() by passing suitable flags | 1657 // allow callers to implement fork() or vfork() by passing suitable flags |
| 1612 // to the clone() system call. | 1658 // to the clone() system call. |
| 1613 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1659 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1614 // FIXME: we should really not have to do that in a trivial policy | 1660 // FIXME: we should really not have to do that in a trivial policy |
| 1615 return ErrorCode(ENOSYS); | 1661 return ErrorCode(ENOSYS); |
| 1616 } else if (sysno == __NR_clone) { | 1662 } else if (sysno == __NR_clone) { |
| 1617 // We have seen two different valid combinations of flags. Glibc | 1663 // We have seen two different valid combinations of flags. Glibc |
| 1618 // uses the more modern flags, sets the TLS from the call to clone(), and | 1664 // uses the more modern flags, sets the TLS from the call to clone(), and |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1638 ErrorCode(ErrorCode::ERR_ALLOWED), | 1684 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1639 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1685 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 1640 kBaseAndroidCloneMask, | 1686 kBaseAndroidCloneMask, |
| 1641 ErrorCode(ErrorCode::ERR_ALLOWED), | 1687 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1642 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); | 1688 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); |
| 1643 } else { | 1689 } else { |
| 1644 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1690 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1645 } | 1691 } |
| 1646 } | 1692 } |
| 1647 | 1693 |
| 1648 ErrorCode PthreadPolicyBitMask(Sandbox *sandbox, int sysno, void *aux) { | 1694 ErrorCode PthreadPolicyBitMask(Sandbox* sandbox, int sysno, void* aux) { |
| 1649 // This policy allows creating threads with pthread_create(). But it | 1695 // This policy allows creating threads with pthread_create(). But it |
| 1650 // doesn't allow any other uses of clone(). Most notably, it does not | 1696 // doesn't allow any other uses of clone(). Most notably, it does not |
| 1651 // allow callers to implement fork() or vfork() by passing suitable flags | 1697 // allow callers to implement fork() or vfork() by passing suitable flags |
| 1652 // to the clone() system call. | 1698 // to the clone() system call. |
| 1653 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1699 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1654 // FIXME: we should really not have to do that in a trivial policy | 1700 // FIXME: we should really not have to do that in a trivial policy |
| 1655 return ErrorCode(ENOSYS); | 1701 return ErrorCode(ENOSYS); |
| 1656 } else if (sysno == __NR_clone) { | 1702 } else if (sysno == __NR_clone) { |
| 1657 // We have seen two different valid combinations of flags. Glibc | 1703 // We have seen two different valid combinations of flags. Glibc |
| 1658 // uses the more modern flags, sets the TLS from the call to clone(), and | 1704 // uses the more modern flags, sets the TLS from the call to clone(), and |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1683 " and futex bits in call to clone()"), | 1729 " and futex bits in call to clone()"), |
| 1684 ErrorCode(ErrorCode::ERR_ALLOWED))), | 1730 ErrorCode(ErrorCode::ERR_ALLOWED))), |
| 1685 sandbox->Trap(PthreadTrapHandler, | 1731 sandbox->Trap(PthreadTrapHandler, |
| 1686 "Missing mandatory CLONE_XXX flags " | 1732 "Missing mandatory CLONE_XXX flags " |
| 1687 "when creating new thread"))); | 1733 "when creating new thread"))); |
| 1688 } else { | 1734 } else { |
| 1689 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1735 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1690 } | 1736 } |
| 1691 } | 1737 } |
| 1692 | 1738 |
| 1693 static void *ThreadFnc(void *arg) { | 1739 static void* ThreadFnc(void* arg) { |
| 1694 ++*reinterpret_cast<int *>(arg); | 1740 ++*reinterpret_cast<int*>(arg); |
| 1695 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); | 1741 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); |
| 1696 return NULL; | 1742 return NULL; |
| 1697 } | 1743 } |
| 1698 | 1744 |
| 1699 static void PthreadTest() { | 1745 static void PthreadTest() { |
| 1700 // Attempt to start a joinable thread. This should succeed. | 1746 // Attempt to start a joinable thread. This should succeed. |
| 1701 pthread_t thread; | 1747 pthread_t thread; |
| 1702 int thread_ran = 0; | 1748 int thread_ran = 0; |
| 1703 BPF_ASSERT(!pthread_create(&thread, NULL, ThreadFnc, &thread_ran)); | 1749 BPF_ASSERT(!pthread_create(&thread, NULL, ThreadFnc, &thread_ran)); |
| 1704 BPF_ASSERT(!pthread_join(thread, NULL)); | 1750 BPF_ASSERT(!pthread_join(thread, NULL)); |
| 1705 BPF_ASSERT(thread_ran); | 1751 BPF_ASSERT(thread_ran); |
| 1706 | 1752 |
| 1707 // Attempt to start a detached thread. This should succeed. | 1753 // Attempt to start a detached thread. This should succeed. |
| 1708 thread_ran = 0; | 1754 thread_ran = 0; |
| 1709 pthread_attr_t attr; | 1755 pthread_attr_t attr; |
| 1710 BPF_ASSERT(!pthread_attr_init(&attr)); | 1756 BPF_ASSERT(!pthread_attr_init(&attr)); |
| 1711 BPF_ASSERT(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); | 1757 BPF_ASSERT(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); |
| 1712 BPF_ASSERT(!pthread_create(&thread, &attr, ThreadFnc, &thread_ran)); | 1758 BPF_ASSERT(!pthread_create(&thread, &attr, ThreadFnc, &thread_ran)); |
| 1713 BPF_ASSERT(!pthread_attr_destroy(&attr)); | 1759 BPF_ASSERT(!pthread_attr_destroy(&attr)); |
| 1714 while (SandboxSyscall(__NR_futex, &thread_ran, FUTEX_WAIT, | 1760 while (SandboxSyscall(__NR_futex, &thread_ran, FUTEX_WAIT, 0, 0, 0, 0) == |
| 1715 0, 0, 0, 0) == -EINTR) { | 1761 -EINTR) { |
| 1716 } | 1762 } |
| 1717 BPF_ASSERT(thread_ran); | 1763 BPF_ASSERT(thread_ran); |
| 1718 | 1764 |
| 1719 // Attempt to fork() a process using clone(). This should fail. We use the | 1765 // Attempt to fork() a process using clone(). This should fail. We use the |
| 1720 // same flags that glibc uses when calling fork(). But we don't actually | 1766 // same flags that glibc uses when calling fork(). But we don't actually |
| 1721 // try calling the fork() implementation in the C run-time library, as | 1767 // try calling the fork() implementation in the C run-time library, as |
| 1722 // run-time libraries other than glibc might call __NR_fork instead of | 1768 // run-time libraries other than glibc might call __NR_fork instead of |
| 1723 // __NR_clone, and that would introduce a bogus test failure. | 1769 // __NR_clone, and that would introduce a bogus test failure. |
| 1724 int pid; | 1770 int pid; |
| 1725 BPF_ASSERT(SandboxSyscall(__NR_clone, | 1771 BPF_ASSERT(SandboxSyscall(__NR_clone, |
| 1726 CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, | 1772 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, |
| 1727 0, 0, &pid) == -EPERM); | 1773 0, |
| 1774 0, |
| 1775 &pid) == -EPERM); |
| 1728 } | 1776 } |
| 1729 | 1777 |
| 1730 BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) { | 1778 BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); } |
| 1731 PthreadTest(); | |
| 1732 } | |
| 1733 | 1779 |
| 1734 BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) { | 1780 BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); } |
| 1735 PthreadTest(); | |
| 1736 } | |
| 1737 | 1781 |
| 1738 } // namespace | 1782 } // namespace |
| OLD | NEW |