| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 // and it helps us accidentally forgetting any of the crucial steps in | 73 // and it helps us accidentally forgetting any of the crucial steps in |
| 74 // setting up the sandbox. But it wouldn't hurt to have at least one test | 74 // setting up the sandbox. But it wouldn't hurt to have at least one test |
| 75 // that explicitly walks through all these steps. | 75 // that explicitly walks through all these steps. |
| 76 | 76 |
| 77 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void *aux) { | 77 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void *aux) { |
| 78 BPF_ASSERT(aux); | 78 BPF_ASSERT(aux); |
| 79 pid_t *pid_ptr = static_cast<pid_t *>(aux); | 79 pid_t *pid_ptr = static_cast<pid_t *>(aux); |
| 80 return (*pid_ptr)++; | 80 return (*pid_ptr)++; |
| 81 } | 81 } |
| 82 | 82 |
| 83 ErrorCode VerboseAPITestingPolicy(int sysno, void *aux) { | 83 ErrorCode VerboseAPITestingPolicy(Sandbox *sandbox, int sysno, void *aux) { |
| 84 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 84 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 85 return ErrorCode(ENOSYS); | 85 return ErrorCode(ENOSYS); |
| 86 } else if (sysno == __NR_getpid) { | 86 } else if (sysno == __NR_getpid) { |
| 87 return Sandbox::Trap(FakeGetPid, aux); | 87 return sandbox->Trap(FakeGetPid, aux); |
| 88 } else { | 88 } else { |
| 89 return ErrorCode(ErrorCode::ERR_ALLOWED); | 89 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 | 92 |
| 93 SANDBOX_TEST(SandboxBpf, VerboseAPITesting) { | 93 SANDBOX_TEST(SandboxBpf, VerboseAPITesting) { |
| 94 if (Sandbox::SupportsSeccompSandbox(-1) == | 94 if (Sandbox::SupportsSeccompSandbox(-1) == |
| 95 playground2::Sandbox::STATUS_AVAILABLE) { | 95 playground2::Sandbox::STATUS_AVAILABLE) { |
| 96 pid_t test_var = 0; | 96 pid_t test_var = 0; |
| 97 playground2::Sandbox::SetSandboxPolicy(VerboseAPITestingPolicy, &test_var); | 97 Sandbox sandbox; |
| 98 playground2::Sandbox::StartSandbox(); | 98 sandbox.SetSandboxPolicy(VerboseAPITestingPolicy, &test_var); |
| 99 sandbox.StartSandbox(); |
| 99 | 100 |
| 100 BPF_ASSERT(test_var == 0); | 101 BPF_ASSERT(test_var == 0); |
| 101 BPF_ASSERT(syscall(__NR_getpid) == 0); | 102 BPF_ASSERT(syscall(__NR_getpid) == 0); |
| 102 BPF_ASSERT(test_var == 1); | 103 BPF_ASSERT(test_var == 1); |
| 103 BPF_ASSERT(syscall(__NR_getpid) == 1); | 104 BPF_ASSERT(syscall(__NR_getpid) == 1); |
| 104 BPF_ASSERT(test_var == 2); | 105 BPF_ASSERT(test_var == 2); |
| 105 | 106 |
| 106 // N.B.: Any future call to getpid() would corrupt the stack. | 107 // N.B.: Any future call to getpid() would corrupt the stack. |
| 107 // This is OK. The SANDBOX_TEST() macro is guaranteed to | 108 // This is OK. The SANDBOX_TEST() macro is guaranteed to |
| 108 // only ever call _exit() after the test completes. | 109 // only ever call _exit() after the test completes. |
| 109 } | 110 } |
| 110 } | 111 } |
| 111 | 112 |
| 112 // A simple blacklist test | 113 // A simple blacklist test |
| 113 | 114 |
| 114 ErrorCode BlacklistNanosleepPolicy(int sysno, void *) { | 115 ErrorCode BlacklistNanosleepPolicy(Sandbox *, int sysno, void *) { |
| 115 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 116 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 116 // FIXME: we should really not have to do that in a trivial policy | 117 // FIXME: we should really not have to do that in a trivial policy |
| 117 return ErrorCode(ENOSYS); | 118 return ErrorCode(ENOSYS); |
| 118 } | 119 } |
| 119 | 120 |
| 120 switch (sysno) { | 121 switch (sysno) { |
| 121 case __NR_nanosleep: | 122 case __NR_nanosleep: |
| 122 return ErrorCode(EACCES); | 123 return ErrorCode(EACCES); |
| 123 default: | 124 default: |
| 124 return ErrorCode(ErrorCode::ERR_ALLOWED); | 125 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 125 } | 126 } |
| 126 } | 127 } |
| 127 | 128 |
| 128 BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | 129 BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { |
| 129 // nanosleep() should be denied | 130 // nanosleep() should be denied |
| 130 const struct timespec ts = {0, 0}; | 131 const struct timespec ts = {0, 0}; |
| 131 errno = 0; | 132 errno = 0; |
| 132 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 133 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| 133 BPF_ASSERT(errno == EACCES); | 134 BPF_ASSERT(errno == EACCES); |
| 134 } | 135 } |
| 135 | 136 |
| 136 // Now do a simple whitelist test | 137 // Now do a simple whitelist test |
| 137 | 138 |
| 138 ErrorCode WhitelistGetpidPolicy(int sysno, void *) { | 139 ErrorCode WhitelistGetpidPolicy(Sandbox *, int sysno, void *) { |
| 139 switch (sysno) { | 140 switch (sysno) { |
| 140 case __NR_getpid: | 141 case __NR_getpid: |
| 141 case __NR_exit_group: | 142 case __NR_exit_group: |
| 142 return ErrorCode(ErrorCode::ERR_ALLOWED); | 143 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 143 default: | 144 default: |
| 144 return ErrorCode(ENOMEM); | 145 return ErrorCode(ENOMEM); |
| 145 } | 146 } |
| 146 } | 147 } |
| 147 | 148 |
| 148 BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { | 149 BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { |
| 149 // getpid() should be allowed | 150 // getpid() should be allowed |
| 150 errno = 0; | 151 errno = 0; |
| 151 BPF_ASSERT(syscall(__NR_getpid) > 0); | 152 BPF_ASSERT(syscall(__NR_getpid) > 0); |
| 152 BPF_ASSERT(errno == 0); | 153 BPF_ASSERT(errno == 0); |
| 153 | 154 |
| 154 // getpgid() should be denied | 155 // getpgid() should be denied |
| 155 BPF_ASSERT(getpgid(0) == -1); | 156 BPF_ASSERT(getpgid(0) == -1); |
| 156 BPF_ASSERT(errno == ENOMEM); | 157 BPF_ASSERT(errno == ENOMEM); |
| 157 } | 158 } |
| 158 | 159 |
| 159 // A simple blacklist policy, with a SIGSYS handler | 160 // A simple blacklist policy, with a SIGSYS handler |
| 160 | 161 |
| 161 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) { | 162 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) { |
| 162 // We also check that the auxiliary data is correct | 163 // We also check that the auxiliary data is correct |
| 163 SANDBOX_ASSERT(aux); | 164 SANDBOX_ASSERT(aux); |
| 164 *(static_cast<int*>(aux)) = kExpectedReturnValue; | 165 *(static_cast<int*>(aux)) = kExpectedReturnValue; |
| 165 return -ENOMEM; | 166 return -ENOMEM; |
| 166 } | 167 } |
| 167 | 168 |
| 168 ErrorCode BlacklistNanosleepPolicySigsys(int sysno, void *aux) { | 169 ErrorCode BlacklistNanosleepPolicySigsys(Sandbox *sandbox, int sysno, |
| 170 void *aux) { |
| 169 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 171 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 170 // FIXME: we should really not have to do that in a trivial policy | 172 // FIXME: we should really not have to do that in a trivial policy |
| 171 return ErrorCode(ENOSYS); | 173 return ErrorCode(ENOSYS); |
| 172 } | 174 } |
| 173 | 175 |
| 174 switch (sysno) { | 176 switch (sysno) { |
| 175 case __NR_nanosleep: | 177 case __NR_nanosleep: |
| 176 return Sandbox::Trap(EnomemHandler, aux); | 178 return sandbox->Trap(EnomemHandler, aux); |
| 177 default: | 179 default: |
| 178 return ErrorCode(ErrorCode::ERR_ALLOWED); | 180 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 179 } | 181 } |
| 180 } | 182 } |
| 181 | 183 |
| 182 BPF_TEST(SandboxBpf, BasicBlacklistWithSigsys, | 184 BPF_TEST(SandboxBpf, BasicBlacklistWithSigsys, |
| 183 BlacklistNanosleepPolicySigsys, int /* BPF_AUX */) { | 185 BlacklistNanosleepPolicySigsys, int /* BPF_AUX */) { |
| 184 // getpid() should work properly | 186 // getpid() should work properly |
| 185 errno = 0; | 187 errno = 0; |
| 186 BPF_ASSERT(syscall(__NR_getpid) > 0); | 188 BPF_ASSERT(syscall(__NR_getpid) > 0); |
| 187 BPF_ASSERT(errno == 0); | 189 BPF_ASSERT(errno == 0); |
| 188 | 190 |
| 189 // Our Auxiliary Data, should be reset by the signal handler | 191 // Our Auxiliary Data, should be reset by the signal handler |
| 190 BPF_AUX = -1; | 192 BPF_AUX = -1; |
| 191 const struct timespec ts = {0, 0}; | 193 const struct timespec ts = {0, 0}; |
| 192 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 194 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| 193 BPF_ASSERT(errno == ENOMEM); | 195 BPF_ASSERT(errno == ENOMEM); |
| 194 | 196 |
| 195 // We expect the signal handler to modify AuxData | 197 // We expect the signal handler to modify AuxData |
| 196 BPF_ASSERT(BPF_AUX == kExpectedReturnValue); | 198 BPF_ASSERT(BPF_AUX == kExpectedReturnValue); |
| 197 } | 199 } |
| 198 | 200 |
| 199 // A simple test that verifies we can return arbitrary errno values. | 201 // A simple test that verifies we can return arbitrary errno values. |
| 200 | 202 |
| 201 ErrorCode ErrnoTestPolicy(int sysno, void *) { | 203 ErrorCode ErrnoTestPolicy(Sandbox *, int sysno, void *) { |
| 202 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 204 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 203 // FIXME: we should really not have to do that in a trivial policy | 205 // FIXME: we should really not have to do that in a trivial policy |
| 204 return ErrorCode(ENOSYS); | 206 return ErrorCode(ENOSYS); |
| 205 } | 207 } |
| 206 | 208 |
| 207 switch (sysno) { | 209 switch (sysno) { |
| 208 case __NR_dup2: | 210 case __NR_dup2: |
| 209 // Pretend that dup2() worked, but don't actually do anything. | 211 // Pretend that dup2() worked, but don't actually do anything. |
| 210 return ErrorCode(0); | 212 return ErrorCode(0); |
| 211 case __NR_setuid: | 213 case __NR_setuid: |
| (...skipping 28 matching lines...) Expand all Loading... |
| 240 // into a no-op by our policy, then we will read \x55. | 242 // into a no-op by our policy, then we will read \x55. |
| 241 BPF_ASSERT(buf[0] == '\x55'); | 243 BPF_ASSERT(buf[0] == '\x55'); |
| 242 | 244 |
| 243 // Verify that we can return the minimum and maximum errno values. | 245 // Verify that we can return the minimum and maximum errno values. |
| 244 BPF_ASSERT(setuid(0) == -1); | 246 BPF_ASSERT(setuid(0) == -1); |
| 245 BPF_ASSERT(errno == 1); | 247 BPF_ASSERT(errno == 1); |
| 246 BPF_ASSERT(setgid(0) == -1); | 248 BPF_ASSERT(setgid(0) == -1); |
| 247 BPF_ASSERT(errno == ErrorCode::ERR_MAX_ERRNO); | 249 BPF_ASSERT(errno == ErrorCode::ERR_MAX_ERRNO); |
| 248 } | 250 } |
| 249 | 251 |
| 252 // Testing the stacking of two sandboxes |
| 253 |
| 254 ErrorCode StackingPolicyPartOne(Sandbox *sandbox, int sysno, void *) { |
| 255 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 256 return ErrorCode(ENOSYS); |
| 257 } |
| 258 |
| 259 switch (sysno) { |
| 260 case __NR_getppid: |
| 261 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
| 262 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 263 ErrorCode(EPERM)); |
| 264 default: |
| 265 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 266 } |
| 267 } |
| 268 |
| 269 ErrorCode StackingPolicyPartTwo(Sandbox *sandbox, int sysno, void *) { |
| 270 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 271 return ErrorCode(ENOSYS); |
| 272 } |
| 273 |
| 274 switch (sysno) { |
| 275 case __NR_getppid: |
| 276 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
| 277 ErrorCode(EINVAL), |
| 278 ErrorCode(ErrorCode::ERR_ALLOWED)); |
| 279 default: |
| 280 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 281 } |
| 282 } |
| 283 |
| 284 BPF_TEST(SandboxBpf, StackingPolicy, StackingPolicyPartOne) { |
| 285 errno = 0; |
| 286 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); |
| 287 BPF_ASSERT(errno == 0); |
| 288 |
| 289 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); |
| 290 BPF_ASSERT(errno == EPERM); |
| 291 |
| 292 // Stack a second sandbox with its own policy. Verify that we can further |
| 293 // restrict filters, but we cannot relax existing filters. |
| 294 Sandbox sandbox; |
| 295 sandbox.SetSandboxPolicy(StackingPolicyPartTwo, NULL); |
| 296 sandbox.StartSandbox(); |
| 297 |
| 298 errno = 0; |
| 299 BPF_ASSERT(syscall(__NR_getppid, 0) == -1); |
| 300 BPF_ASSERT(errno == EINVAL); |
| 301 |
| 302 BPF_ASSERT(syscall(__NR_getppid, 1) == -1); |
| 303 BPF_ASSERT(errno == EPERM); |
| 304 } |
| 305 |
| 250 // A more complex, but synthetic policy. This tests the correctness of the BPF | 306 // A more complex, but synthetic policy. This tests the correctness of the BPF |
| 251 // program by iterating through all syscalls and checking for an errno that | 307 // program by iterating through all syscalls and checking for an errno that |
| 252 // depends on the syscall number. Unlike the Verifier, this exercises the BPF | 308 // depends on the syscall number. Unlike the Verifier, this exercises the BPF |
| 253 // interpreter in the kernel. | 309 // interpreter in the kernel. |
| 254 | 310 |
| 255 // We try to make sure we exercise optimizations in the BPF compiler. We make | 311 // We try to make sure we exercise optimizations in the BPF compiler. We make |
| 256 // sure that the compiler can have an opportunity to coalesce syscalls with | 312 // sure that the compiler can have an opportunity to coalesce syscalls with |
| 257 // contiguous numbers and we also make sure that disjoint sets can return the | 313 // contiguous numbers and we also make sure that disjoint sets can return the |
| 258 // same errno. | 314 // same errno. |
| 259 int SysnoToRandomErrno(int sysno) { | 315 int SysnoToRandomErrno(int sysno) { |
| 260 // Small contiguous sets of 3 system calls return an errno equal to the | 316 // Small contiguous sets of 3 system calls return an errno equal to the |
| 261 // index of that set + 1 (so that we never return a NUL errno). | 317 // index of that set + 1 (so that we never return a NUL errno). |
| 262 return ((sysno & ~3) >> 2) % 29 + 1; | 318 return ((sysno & ~3) >> 2) % 29 + 1; |
| 263 } | 319 } |
| 264 | 320 |
| 265 ErrorCode SyntheticPolicy(int sysno, void *) { | 321 ErrorCode SyntheticPolicy(Sandbox *, int sysno, void *) { |
| 266 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 322 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 267 // FIXME: we should really not have to do that in a trivial policy | 323 // FIXME: we should really not have to do that in a trivial policy |
| 268 return ErrorCode(ENOSYS); | 324 return ErrorCode(ENOSYS); |
| 269 } | 325 } |
| 270 | 326 |
| 271 // TODO(jorgelo): remove this once the new code generator lands. | 327 // TODO(jorgelo): remove this once the new code generator lands. |
| 272 #if defined(__arm__) | 328 #if defined(__arm__) |
| 273 if (sysno > static_cast<int>(MAX_PUBLIC_SYSCALL)) { | 329 if (sysno > static_cast<int>(MAX_PUBLIC_SYSCALL)) { |
| 274 return ErrorCode(ENOSYS); | 330 return ErrorCode(ENOSYS); |
| 275 } | 331 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). | 369 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). |
| 314 int ArmPrivateSysnoToErrno(int sysno) { | 370 int ArmPrivateSysnoToErrno(int sysno) { |
| 315 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && | 371 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && |
| 316 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 372 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
| 317 return (sysno - MIN_PRIVATE_SYSCALL) + 1; | 373 return (sysno - MIN_PRIVATE_SYSCALL) + 1; |
| 318 } else { | 374 } else { |
| 319 return ENOSYS; | 375 return ENOSYS; |
| 320 } | 376 } |
| 321 } | 377 } |
| 322 | 378 |
| 323 ErrorCode ArmPrivatePolicy(int sysno, void *) { | 379 ErrorCode ArmPrivatePolicy(Sandbox *, int sysno, void *) { |
| 324 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 380 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 325 // FIXME: we should really not have to do that in a trivial policy. | 381 // FIXME: we should really not have to do that in a trivial policy. |
| 326 return ErrorCode(ENOSYS); | 382 return ErrorCode(ENOSYS); |
| 327 } | 383 } |
| 328 | 384 |
| 329 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual | 385 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual |
| 330 // ARM private system calls. | 386 // ARM private system calls. |
| 331 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && | 387 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && |
| 332 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 388 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
| 333 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); | 389 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 353 | 409 |
| 354 // Verify that within the callback function all filtering is temporarily | 410 // Verify that within the callback function all filtering is temporarily |
| 355 // disabled. | 411 // disabled. |
| 356 BPF_ASSERT(syscall(__NR_getpid) > 1); | 412 BPF_ASSERT(syscall(__NR_getpid) > 1); |
| 357 | 413 |
| 358 // Verify that we can now call the underlying system call without causing | 414 // Verify that we can now call the underlying system call without causing |
| 359 // infinite recursion. | 415 // infinite recursion. |
| 360 return Sandbox::ForwardSyscall(args); | 416 return Sandbox::ForwardSyscall(args); |
| 361 } | 417 } |
| 362 | 418 |
| 363 ErrorCode GreyListedPolicy(int sysno, void *aux) { | 419 ErrorCode GreyListedPolicy(Sandbox *sandbox, int sysno, void *aux) { |
| 364 // The use of UnsafeTrap() causes us to print a warning message. This is | 420 // The use of UnsafeTrap() causes us to print a warning message. This is |
| 365 // generally desirable, but it results in the unittest failing, as it doesn't | 421 // generally desirable, but it results in the unittest failing, as it doesn't |
| 366 // expect any messages on "stderr". So, temporarily disable messages. The | 422 // expect any messages on "stderr". So, temporarily disable messages. The |
| 367 // BPF_TEST() is guaranteed to turn messages back on, after the policy | 423 // BPF_TEST() is guaranteed to turn messages back on, after the policy |
| 368 // function has completed. | 424 // function has completed. |
| 369 setenv(kSandboxDebuggingEnv, "t", 0); | 425 setenv(kSandboxDebuggingEnv, "t", 0); |
| 370 Die::SuppressInfoMessages(true); | 426 Die::SuppressInfoMessages(true); |
| 371 | 427 |
| 372 // Some system calls must always be allowed, if our policy wants to make | 428 // Some system calls must always be allowed, if our policy wants to make |
| 373 // use of UnsafeTrap() | 429 // use of UnsafeTrap() |
| 374 if (sysno == __NR_rt_sigprocmask || | 430 if (sysno == __NR_rt_sigprocmask || |
| 375 sysno == __NR_rt_sigreturn | 431 sysno == __NR_rt_sigreturn |
| 376 #if defined(__NR_sigprocmask) | 432 #if defined(__NR_sigprocmask) |
| 377 || sysno == __NR_sigprocmask | 433 || sysno == __NR_sigprocmask |
| 378 #endif | 434 #endif |
| 379 #if defined(__NR_sigreturn) | 435 #if defined(__NR_sigreturn) |
| 380 || sysno == __NR_sigreturn | 436 || sysno == __NR_sigreturn |
| 381 #endif | 437 #endif |
| 382 ) { | 438 ) { |
| 383 return ErrorCode(ErrorCode::ERR_ALLOWED); | 439 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 384 } else if (sysno == __NR_getpid) { | 440 } else if (sysno == __NR_getpid) { |
| 385 // Disallow getpid() | 441 // Disallow getpid() |
| 386 return ErrorCode(EPERM); | 442 return ErrorCode(EPERM); |
| 387 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 443 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
| 388 // Allow (and count) all other system calls. | 444 // Allow (and count) all other system calls. |
| 389 return Sandbox::UnsafeTrap(CountSyscalls, aux); | 445 return sandbox->UnsafeTrap(CountSyscalls, aux); |
| 390 } else { | 446 } else { |
| 391 return ErrorCode(ENOSYS); | 447 return ErrorCode(ENOSYS); |
| 392 } | 448 } |
| 393 } | 449 } |
| 394 | 450 |
| 395 BPF_TEST(SandboxBpf, GreyListedPolicy, | 451 BPF_TEST(SandboxBpf, GreyListedPolicy, |
| 396 GreyListedPolicy, int /* BPF_AUX */) { | 452 GreyListedPolicy, int /* BPF_AUX */) { |
| 397 BPF_ASSERT(syscall(__NR_getpid) == -1); | 453 BPF_ASSERT(syscall(__NR_getpid) == -1); |
| 398 BPF_ASSERT(errno == EPERM); | 454 BPF_ASSERT(errno == EPERM); |
| 399 BPF_ASSERT(BPF_AUX == 0); | 455 BPF_ASSERT(BPF_AUX == 0); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 423 if (args.args[0] == PR_CAPBSET_DROP && | 479 if (args.args[0] == PR_CAPBSET_DROP && |
| 424 static_cast<int>(args.args[1]) == -1) { | 480 static_cast<int>(args.args[1]) == -1) { |
| 425 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always | 481 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always |
| 426 // return an error. But our handler allows this call. | 482 // return an error. But our handler allows this call. |
| 427 return 0; | 483 return 0; |
| 428 } else { | 484 } else { |
| 429 return Sandbox::ForwardSyscall(args); | 485 return Sandbox::ForwardSyscall(args); |
| 430 } | 486 } |
| 431 } | 487 } |
| 432 | 488 |
| 433 ErrorCode PrctlPolicy(int sysno, void *aux) { | 489 ErrorCode PrctlPolicy(Sandbox *sandbox, int sysno, void *aux) { |
| 434 setenv(kSandboxDebuggingEnv, "t", 0); | 490 setenv(kSandboxDebuggingEnv, "t", 0); |
| 435 Die::SuppressInfoMessages(true); | 491 Die::SuppressInfoMessages(true); |
| 436 | 492 |
| 437 if (sysno == __NR_prctl) { | 493 if (sysno == __NR_prctl) { |
| 438 // Handle prctl() inside an UnsafeTrap() | 494 // Handle prctl() inside an UnsafeTrap() |
| 439 return Sandbox::UnsafeTrap(PrctlHandler, NULL); | 495 return sandbox->UnsafeTrap(PrctlHandler, NULL); |
| 440 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 496 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
| 441 // Allow all other system calls. | 497 // Allow all other system calls. |
| 442 return ErrorCode(ErrorCode::ERR_ALLOWED); | 498 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 443 } else { | 499 } else { |
| 444 return ErrorCode(ENOSYS); | 500 return ErrorCode(ENOSYS); |
| 445 } | 501 } |
| 446 } | 502 } |
| 447 | 503 |
| 448 BPF_TEST(SandboxBpf, ForwardSyscall, PrctlPolicy) { | 504 BPF_TEST(SandboxBpf, ForwardSyscall, PrctlPolicy) { |
| 449 // This call should never be allowed. But our policy will intercept it and | 505 // This call should never be allowed. But our policy will intercept it and |
| (...skipping 15 matching lines...) Expand all Loading... |
| 465 // unaffected by our policy. | 521 // unaffected by our policy. |
| 466 struct utsname uts = { }; | 522 struct utsname uts = { }; |
| 467 BPF_ASSERT(!uname(&uts)); | 523 BPF_ASSERT(!uname(&uts)); |
| 468 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); | 524 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); |
| 469 } | 525 } |
| 470 | 526 |
| 471 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void *) { | 527 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void *) { |
| 472 return Sandbox::ForwardSyscall(args); | 528 return Sandbox::ForwardSyscall(args); |
| 473 } | 529 } |
| 474 | 530 |
| 475 ErrorCode RedirectAllSyscallsPolicy(int sysno, void *aux) { | 531 ErrorCode RedirectAllSyscallsPolicy(Sandbox *sandbox, int sysno, void *aux) { |
| 476 setenv(kSandboxDebuggingEnv, "t", 0); | 532 setenv(kSandboxDebuggingEnv, "t", 0); |
| 477 Die::SuppressInfoMessages(true); | 533 Die::SuppressInfoMessages(true); |
| 478 | 534 |
| 479 // Some system calls must always be allowed, if our policy wants to make | 535 // Some system calls must always be allowed, if our policy wants to make |
| 480 // use of UnsafeTrap() | 536 // use of UnsafeTrap() |
| 481 if (sysno == __NR_rt_sigprocmask || | 537 if (sysno == __NR_rt_sigprocmask || |
| 482 sysno == __NR_rt_sigreturn | 538 sysno == __NR_rt_sigreturn |
| 483 #if defined(__NR_sigprocmask) | 539 #if defined(__NR_sigprocmask) |
| 484 || sysno == __NR_sigprocmask | 540 || sysno == __NR_sigprocmask |
| 485 #endif | 541 #endif |
| 486 #if defined(__NR_sigreturn) | 542 #if defined(__NR_sigreturn) |
| 487 || sysno == __NR_sigreturn | 543 || sysno == __NR_sigreturn |
| 488 #endif | 544 #endif |
| 489 ) { | 545 ) { |
| 490 return ErrorCode(ErrorCode::ERR_ALLOWED); | 546 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 491 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 547 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
| 492 return Sandbox::UnsafeTrap(AllowRedirectedSyscall, aux); | 548 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux); |
| 493 } else { | 549 } else { |
| 494 return ErrorCode(ENOSYS); | 550 return ErrorCode(ENOSYS); |
| 495 } | 551 } |
| 496 } | 552 } |
| 497 | 553 |
| 498 int bus_handler_fd_ = -1; | 554 int bus_handler_fd_ = -1; |
| 499 | 555 |
| 500 void SigBusHandler(int, siginfo_t *info, void *void_context) { | 556 void SigBusHandler(int, siginfo_t *info, void *void_context) { |
| 501 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); | 557 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); |
| 502 } | 558 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 // the openat() system call. | 669 // the openat() system call. |
| 614 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); | 670 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); |
| 615 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), | 671 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), |
| 616 static_cast<int>(args.args[2])); | 672 static_cast<int>(args.args[2])); |
| 617 default: | 673 default: |
| 618 BPF_ASSERT(false); | 674 BPF_ASSERT(false); |
| 619 return -ENOSYS; | 675 return -ENOSYS; |
| 620 } | 676 } |
| 621 } | 677 } |
| 622 | 678 |
| 623 ErrorCode DenyOpenPolicy(int sysno, void *aux) { | 679 ErrorCode DenyOpenPolicy(Sandbox *sandbox, int sysno, void *aux) { |
| 624 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux); | 680 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux); |
| 625 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 681 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 626 return ErrorCode(ENOSYS); | 682 return ErrorCode(ENOSYS); |
| 627 } | 683 } |
| 628 | 684 |
| 629 switch (sysno) { | 685 switch (sysno) { |
| 630 case __NR_open: | 686 case __NR_open: |
| 631 case __NR_openat: | 687 case __NR_openat: |
| 632 // We get a InitializedOpenBroker class, but our trap handler wants | 688 // We get a InitializedOpenBroker class, but our trap handler wants |
| 633 // the BrokerProcess object. | 689 // the BrokerProcess object. |
| 634 return ErrorCode(Sandbox::Trap(BrokerOpenTrapHandler, | 690 return ErrorCode(sandbox->Trap(BrokerOpenTrapHandler, |
| 635 iob->broker_process())); | 691 iob->broker_process())); |
| 636 default: | 692 default: |
| 637 return ErrorCode(ErrorCode::ERR_ALLOWED); | 693 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 638 } | 694 } |
| 639 } | 695 } |
| 640 | 696 |
| 641 // We use a InitializedOpenBroker class, so that we can run unsandboxed | 697 // We use a InitializedOpenBroker class, so that we can run unsandboxed |
| 642 // code in its constructor, which is the only way to do so in a BPF_TEST. | 698 // code in its constructor, which is the only way to do so in a BPF_TEST. |
| 643 BPF_TEST(SandboxBpf, UseOpenBroker, DenyOpenPolicy, | 699 BPF_TEST(SandboxBpf, UseOpenBroker, DenyOpenPolicy, |
| 644 InitializedOpenBroker /* BPF_AUX */) { | 700 InitializedOpenBroker /* BPF_AUX */) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 668 | 724 |
| 669 // This is also white listed and does exist. | 725 // This is also white listed and does exist. |
| 670 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); | 726 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); |
| 671 BPF_ASSERT(cpu_info_fd >= 0); | 727 BPF_ASSERT(cpu_info_fd >= 0); |
| 672 char buf[1024]; | 728 char buf[1024]; |
| 673 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); | 729 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); |
| 674 } | 730 } |
| 675 | 731 |
| 676 // Simple test demonstrating how to use Sandbox::Cond() | 732 // Simple test demonstrating how to use Sandbox::Cond() |
| 677 | 733 |
| 678 ErrorCode SimpleCondTestPolicy(int sysno, void *) { | 734 ErrorCode SimpleCondTestPolicy(Sandbox *sandbox, int sysno, void *) { |
| 679 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 735 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 680 // FIXME: we should really not have to do that in a trivial policy | 736 // FIXME: we should really not have to do that in a trivial policy |
| 681 return ErrorCode(ENOSYS); | 737 return ErrorCode(ENOSYS); |
| 682 } | 738 } |
| 683 | 739 |
| 684 // We deliberately return unusual errno values upon failure, so that we | 740 // We deliberately return unusual errno values upon failure, so that we |
| 685 // can uniquely test for these values. In a "real" policy, you would want | 741 // can uniquely test for these values. In a "real" policy, you would want |
| 686 // to return more traditional values. | 742 // to return more traditional values. |
| 687 switch (sysno) { | 743 switch (sysno) { |
| 688 case __NR_open: | 744 case __NR_open: |
| 689 // Allow opening files for reading, but don't allow writing. | 745 // Allow opening files for reading, but don't allow writing. |
| 690 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); | 746 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); |
| 691 return Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 747 return sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 692 O_ACCMODE /* 0x3 */, | 748 O_ACCMODE /* 0x3 */, |
| 693 ErrorCode(EROFS), | 749 ErrorCode(EROFS), |
| 694 ErrorCode(ErrorCode::ERR_ALLOWED)); | 750 ErrorCode(ErrorCode::ERR_ALLOWED)); |
| 695 case __NR_prctl: | 751 case __NR_prctl: |
| 696 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but | 752 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but |
| 697 // disallow everything else. | 753 // disallow everything else. |
| 698 return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 754 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 699 PR_SET_DUMPABLE, | 755 PR_SET_DUMPABLE, |
| 700 ErrorCode(ErrorCode::ERR_ALLOWED), | 756 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 701 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 757 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 702 PR_GET_DUMPABLE, | 758 PR_GET_DUMPABLE, |
| 703 ErrorCode(ErrorCode::ERR_ALLOWED), | 759 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 704 ErrorCode(ENOMEM))); | 760 ErrorCode(ENOMEM))); |
| 705 default: | 761 default: |
| 706 return ErrorCode(ErrorCode::ERR_ALLOWED); | 762 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 707 } | 763 } |
| 708 } | 764 } |
| 709 | 765 |
| 710 BPF_TEST(SandboxBpf, SimpleCondTest, SimpleCondTestPolicy) { | 766 BPF_TEST(SandboxBpf, SimpleCondTest, SimpleCondTestPolicy) { |
| 711 int fd; | 767 int fd; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 } | 809 } |
| 754 | 810 |
| 755 ~EqualityStressTest() { | 811 ~EqualityStressTest() { |
| 756 for (std::vector<ArgValue *>::iterator iter = arg_values_.begin(); | 812 for (std::vector<ArgValue *>::iterator iter = arg_values_.begin(); |
| 757 iter != arg_values_.end(); | 813 iter != arg_values_.end(); |
| 758 ++iter) { | 814 ++iter) { |
| 759 DeleteArgValue(*iter); | 815 DeleteArgValue(*iter); |
| 760 } | 816 } |
| 761 } | 817 } |
| 762 | 818 |
| 763 ErrorCode Policy(int sysno) { | 819 ErrorCode Policy(Sandbox *sandbox, int sysno) { |
| 764 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 820 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 765 // FIXME: we should really not have to do that in a trivial policy | 821 // FIXME: we should really not have to do that in a trivial policy |
| 766 return ErrorCode(ENOSYS); | 822 return ErrorCode(ENOSYS); |
| 767 } else if (sysno < 0 || sysno >= (int)arg_values_.size() || | 823 } else if (sysno < 0 || sysno >= (int)arg_values_.size() || |
| 768 IsReservedSyscall(sysno)) { | 824 IsReservedSyscall(sysno)) { |
| 769 // We only return ErrorCode values for the system calls that | 825 // We only return ErrorCode values for the system calls that |
| 770 // are part of our test data. Every other system call remains | 826 // are part of our test data. Every other system call remains |
| 771 // allowed. | 827 // allowed. |
| 772 return ErrorCode(ErrorCode::ERR_ALLOWED); | 828 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 773 } else { | 829 } else { |
| 774 // ToErrorCode() turns an ArgValue object into an ErrorCode that is | 830 // ToErrorCode() turns an ArgValue object into an ErrorCode that is |
| 775 // suitable for use by a sandbox policy. | 831 // suitable for use by a sandbox policy. |
| 776 return ToErrorCode(arg_values_[sysno]); | 832 return ToErrorCode(sandbox, arg_values_[sysno]); |
| 777 } | 833 } |
| 778 } | 834 } |
| 779 | 835 |
| 780 void VerifyFilter() { | 836 void VerifyFilter() { |
| 781 // Iterate over all system calls. Skip the system calls that have | 837 // Iterate over all system calls. Skip the system calls that have |
| 782 // previously been determined as being reserved. | 838 // previously been determined as being reserved. |
| 783 for (int sysno = 0; sysno < (int)arg_values_.size(); ++sysno) { | 839 for (int sysno = 0; sysno < (int)arg_values_.size(); ++sysno) { |
| 784 if (!arg_values_[sysno]) { | 840 if (!arg_values_[sysno]) { |
| 785 // Skip reserved system calls. | 841 // Skip reserved system calls. |
| 786 continue; | 842 continue; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 } | 972 } |
| 917 delete[] arg_value->tests; | 973 delete[] arg_value->tests; |
| 918 } | 974 } |
| 919 if (!arg_value->err) { | 975 if (!arg_value->err) { |
| 920 DeleteArgValue(arg_value->arg_value); | 976 DeleteArgValue(arg_value->arg_value); |
| 921 } | 977 } |
| 922 delete arg_value; | 978 delete arg_value; |
| 923 } | 979 } |
| 924 } | 980 } |
| 925 | 981 |
| 926 ErrorCode ToErrorCode(ArgValue *arg_value) { | 982 ErrorCode ToErrorCode(Sandbox *sandbox, ArgValue *arg_value) { |
| 927 // Compute the ErrorCode that should be returned, if none of our | 983 // Compute the ErrorCode that should be returned, if none of our |
| 928 // tests succeed (i.e. the system call parameter doesn't match any | 984 // tests succeed (i.e. the system call parameter doesn't match any |
| 929 // of the values in arg_value->tests[].k_value). | 985 // of the values in arg_value->tests[].k_value). |
| 930 ErrorCode err; | 986 ErrorCode err; |
| 931 if (arg_value->err) { | 987 if (arg_value->err) { |
| 932 // If this was a leaf node, return the errno value that we expect to | 988 // If this was a leaf node, return the errno value that we expect to |
| 933 // return from the BPF filter program. | 989 // return from the BPF filter program. |
| 934 err = ErrorCode(arg_value->err); | 990 err = ErrorCode(arg_value->err); |
| 935 } else { | 991 } else { |
| 936 // If this wasn't a leaf node yet, recursively descend into the rest | 992 // If this wasn't a leaf node yet, recursively descend into the rest |
| 937 // of the tree. This will end up adding a few more Sandbox::Cond() | 993 // of the tree. This will end up adding a few more Sandbox::Cond() |
| 938 // tests to our ErrorCode. | 994 // tests to our ErrorCode. |
| 939 err = ToErrorCode(arg_value->arg_value); | 995 err = ToErrorCode(sandbox, arg_value->arg_value); |
| 940 } | 996 } |
| 941 | 997 |
| 942 // Now, iterate over all the test cases that we want to compare against. | 998 // Now, iterate over all the test cases that we want to compare against. |
| 943 // This builds a chain of Sandbox::Cond() tests | 999 // This builds a chain of Sandbox::Cond() tests |
| 944 // (aka "if ... elif ... elif ... elif ... fi") | 1000 // (aka "if ... elif ... elif ... elif ... fi") |
| 945 for (int n = arg_value->size; n-- > 0; ) { | 1001 for (int n = arg_value->size; n-- > 0; ) { |
| 946 ErrorCode matched; | 1002 ErrorCode matched; |
| 947 // Again, we distinguish between leaf nodes and subtrees. | 1003 // Again, we distinguish between leaf nodes and subtrees. |
| 948 if (arg_value->tests[n].err) { | 1004 if (arg_value->tests[n].err) { |
| 949 matched = ErrorCode(arg_value->tests[n].err); | 1005 matched = ErrorCode(arg_value->tests[n].err); |
| 950 } else { | 1006 } else { |
| 951 matched = ToErrorCode(arg_value->tests[n].arg_value); | 1007 matched = ToErrorCode(sandbox, arg_value->tests[n].arg_value); |
| 952 } | 1008 } |
| 953 // For now, all of our tests are limited to 32bit. | 1009 // For now, all of our tests are limited to 32bit. |
| 954 // We have separate tests that check the behavior of 32bit vs. 64bit | 1010 // We have separate tests that check the behavior of 32bit vs. 64bit |
| 955 // conditional expressions. | 1011 // conditional expressions. |
| 956 err = Sandbox::Cond(arg_value->argno, ErrorCode::TP_32BIT, | 1012 err = sandbox->Cond(arg_value->argno, ErrorCode::TP_32BIT, |
| 957 ErrorCode::OP_EQUAL, arg_value->tests[n].k_value, | 1013 ErrorCode::OP_EQUAL, arg_value->tests[n].k_value, |
| 958 matched, err); | 1014 matched, err); |
| 959 } | 1015 } |
| 960 return err; | 1016 return err; |
| 961 } | 1017 } |
| 962 | 1018 |
| 963 void Verify(int sysno, intptr_t *args, const ArgValue& arg_value) { | 1019 void Verify(int sysno, intptr_t *args, const ArgValue& arg_value) { |
| 964 uint32_t mismatched = 0; | 1020 uint32_t mismatched = 0; |
| 965 // Iterate over all the k_values in arg_value.tests[] and verify that | 1021 // Iterate over all the k_values in arg_value.tests[] and verify that |
| 966 // we see the expected return values from system calls, when we pass | 1022 // we see the expected return values from system calls, when we pass |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 | 1070 |
| 1015 // Don't increase these values. We are pushing the limits of the maximum | 1071 // Don't increase these values. We are pushing the limits of the maximum |
| 1016 // BPF program that the kernel will allow us to load. If the values are | 1072 // BPF program that the kernel will allow us to load. If the values are |
| 1017 // increased too much, the test will start failing. | 1073 // increased too much, the test will start failing. |
| 1018 static const int kNumIterations = 3; | 1074 static const int kNumIterations = 3; |
| 1019 static const int kNumTestCases = 40; | 1075 static const int kNumTestCases = 40; |
| 1020 static const int kMaxFanOut = 3; | 1076 static const int kMaxFanOut = 3; |
| 1021 static const int kMaxArgs = 6; | 1077 static const int kMaxArgs = 6; |
| 1022 }; | 1078 }; |
| 1023 | 1079 |
| 1024 ErrorCode EqualityStressTestPolicy(int sysno, void *aux) { | 1080 ErrorCode EqualityStressTestPolicy(Sandbox *sandbox, int sysno, void *aux) { |
| 1025 return reinterpret_cast<EqualityStressTest *>(aux)->Policy(sysno); | 1081 return reinterpret_cast<EqualityStressTest *>(aux)->Policy(sandbox, sysno); |
| 1026 } | 1082 } |
| 1027 | 1083 |
| 1028 BPF_TEST(SandboxBpf, EqualityTests, EqualityStressTestPolicy, | 1084 BPF_TEST(SandboxBpf, EqualityTests, EqualityStressTestPolicy, |
| 1029 EqualityStressTest /* BPF_AUX */) { | 1085 EqualityStressTest /* BPF_AUX */) { |
| 1030 BPF_AUX.VerifyFilter(); | 1086 BPF_AUX.VerifyFilter(); |
| 1031 } | 1087 } |
| 1032 | 1088 |
| 1033 ErrorCode EqualityArgumentWidthPolicy(int sysno, void *) { | 1089 ErrorCode EqualityArgumentWidthPolicy(Sandbox *sandbox, int sysno, void *) { |
| 1034 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1090 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1035 // FIXME: we should really not have to do that in a trivial policy | 1091 // FIXME: we should really not have to do that in a trivial policy |
| 1036 return ErrorCode(ENOSYS); | 1092 return ErrorCode(ENOSYS); |
| 1037 } else if (sysno == __NR_uname) { | 1093 } else if (sysno == __NR_uname) { |
| 1038 return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1094 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
| 1039 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1095 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 1040 0x55555555, ErrorCode(1), ErrorCode(2)), | 1096 0x55555555, ErrorCode(1), ErrorCode(2)), |
| 1041 // The BPF compiler and the BPF interpreter in the kernel are | 1097 // The BPF compiler and the BPF interpreter in the kernel are |
| 1042 // (mostly) agnostic of the host platform's word size. The compiler | 1098 // (mostly) agnostic of the host platform's word size. The compiler |
| 1043 // will happily generate code that tests a 64bit value, and the | 1099 // will happily generate code that tests a 64bit value, and the |
| 1044 // interpreter will happily perform this test. | 1100 // interpreter will happily perform this test. |
| 1045 // But unless there is a kernel bug, there is no way for us to pass | 1101 // But unless there is a kernel bug, there is no way for us to pass |
| 1046 // in a 64bit quantity on a 32bit platform. The upper 32bits should | 1102 // in a 64bit quantity on a 32bit platform. The upper 32bits should |
| 1047 // always be zero. So, this test should always evaluate as false on | 1103 // always be zero. So, this test should always evaluate as false on |
| 1048 // 32bit systems. | 1104 // 32bit systems. |
| 1049 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_EQUAL, | 1105 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_EQUAL, |
| 1050 0x55555555AAAAAAAAULL, ErrorCode(1), ErrorCode(2))); | 1106 0x55555555AAAAAAAAULL, ErrorCode(1), ErrorCode(2))); |
| 1051 } else { | 1107 } else { |
| 1052 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1108 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1053 } | 1109 } |
| 1054 } | 1110 } |
| 1055 | 1111 |
| 1056 BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { | 1112 BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { |
| 1057 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); | 1113 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); |
| 1058 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); | 1114 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); |
| 1059 #if __SIZEOF_POINTER__ > 4 | 1115 #if __SIZEOF_POINTER__ > 4 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1073 // On 32bit machines, there is no way to pass a 64bit argument through the | 1129 // On 32bit machines, there is no way to pass a 64bit argument through the |
| 1074 // syscall interface. So, we have to skip the part of the test that requires | 1130 // syscall interface. So, we have to skip the part of the test that requires |
| 1075 // 64bit arguments. | 1131 // 64bit arguments. |
| 1076 BPF_DEATH_TEST(SandboxBpf, EqualityArgumentUnallowed64bit, | 1132 BPF_DEATH_TEST(SandboxBpf, EqualityArgumentUnallowed64bit, |
| 1077 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1133 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
| 1078 EqualityArgumentWidthPolicy) { | 1134 EqualityArgumentWidthPolicy) { |
| 1079 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); | 1135 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); |
| 1080 } | 1136 } |
| 1081 #endif | 1137 #endif |
| 1082 | 1138 |
| 1083 ErrorCode EqualityWithNegativeArgumentsPolicy(int sysno, void *) { | 1139 ErrorCode EqualityWithNegativeArgumentsPolicy(Sandbox *sandbox, int sysno, |
| 1140 void *) { |
| 1084 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1141 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1085 // FIXME: we should really not have to do that in a trivial policy | 1142 // FIXME: we should really not have to do that in a trivial policy |
| 1086 return ErrorCode(ENOSYS); | 1143 return ErrorCode(ENOSYS); |
| 1087 } else if (sysno == __NR_uname) { | 1144 } else if (sysno == __NR_uname) { |
| 1088 return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1145 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 1089 0xFFFFFFFF, ErrorCode(1), ErrorCode(2)); | 1146 0xFFFFFFFF, ErrorCode(1), ErrorCode(2)); |
| 1090 } else { | 1147 } else { |
| 1091 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1148 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1092 } | 1149 } |
| 1093 } | 1150 } |
| 1094 | 1151 |
| 1095 BPF_TEST(SandboxBpf, EqualityWithNegativeArguments, | 1152 BPF_TEST(SandboxBpf, EqualityWithNegativeArguments, |
| 1096 EqualityWithNegativeArgumentsPolicy) { | 1153 EqualityWithNegativeArgumentsPolicy) { |
| 1097 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); | 1154 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); |
| 1098 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); | 1155 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); |
| 1099 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); | 1156 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); |
| 1100 } | 1157 } |
| 1101 | 1158 |
| 1102 #if __SIZEOF_POINTER__ > 4 | 1159 #if __SIZEOF_POINTER__ > 4 |
| 1103 BPF_DEATH_TEST(SandboxBpf, EqualityWithNegative64bitArguments, | 1160 BPF_DEATH_TEST(SandboxBpf, EqualityWithNegative64bitArguments, |
| 1104 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1161 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
| 1105 EqualityWithNegativeArgumentsPolicy) { | 1162 EqualityWithNegativeArgumentsPolicy) { |
| 1106 // When expecting a 32bit system call argument, we look at the MSB of the | 1163 // When expecting a 32bit system call argument, we look at the MSB of the |
| 1107 // 64bit value and allow both "0" and "-1". But the latter is allowed only | 1164 // 64bit value and allow both "0" and "-1". But the latter is allowed only |
| 1108 // iff the LSB was negative. So, this death test should error out. | 1165 // iff the LSB was negative. So, this death test should error out. |
| 1109 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); | 1166 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); |
| 1110 } | 1167 } |
| 1111 #endif | 1168 #endif |
| 1112 | 1169 |
| 1113 ErrorCode AllBitTestPolicy(int sysno, void *) { | 1170 ErrorCode AllBitTestPolicy(Sandbox *sandbox, int sysno, void *) { |
| 1114 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of | 1171 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of |
| 1115 // different bitmasks. We try to find bitmasks that could conceivably | 1172 // different bitmasks. We try to find bitmasks that could conceivably |
| 1116 // touch corner cases. | 1173 // touch corner cases. |
| 1117 // For all of these tests, we override the uname(). We can make use with | 1174 // For all of these tests, we override the uname(). We can make use with |
| 1118 // a single system call number, as we use the first system call argument to | 1175 // a single system call number, as we use the first system call argument to |
| 1119 // select the different bit masks that we want to test against. | 1176 // select the different bit masks that we want to test against. |
| 1120 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1177 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1121 // FIXME: we should really not have to do that in a trivial policy | 1178 // FIXME: we should really not have to do that in a trivial policy |
| 1122 return ErrorCode(ENOSYS); | 1179 return ErrorCode(ENOSYS); |
| 1123 } else if (sysno == __NR_uname) { | 1180 } else if (sysno == __NR_uname) { |
| 1124 return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1181 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
| 1125 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1182 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1126 0x0, | 1183 0x0, |
| 1127 ErrorCode(1), ErrorCode(0)), | 1184 ErrorCode(1), ErrorCode(0)), |
| 1128 | 1185 |
| 1129 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, | 1186 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, |
| 1130 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1187 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1131 0x1, | 1188 0x1, |
| 1132 ErrorCode(1), ErrorCode(0)), | 1189 ErrorCode(1), ErrorCode(0)), |
| 1133 | 1190 |
| 1134 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 2, | 1191 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 2, |
| 1135 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1192 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1136 0x3, | 1193 0x3, |
| 1137 ErrorCode(1), ErrorCode(0)), | 1194 ErrorCode(1), ErrorCode(0)), |
| 1138 | 1195 |
| 1139 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 3, | 1196 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 3, |
| 1140 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1197 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1198 0x80000000, |
| 1199 ErrorCode(1), ErrorCode(0)), |
| 1200 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 4, |
| 1201 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1202 0x0, |
| 1203 ErrorCode(1), ErrorCode(0)), |
| 1204 |
| 1205 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 5, |
| 1206 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1207 0x1, |
| 1208 ErrorCode(1), ErrorCode(0)), |
| 1209 |
| 1210 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 6, |
| 1211 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1212 0x3, |
| 1213 ErrorCode(1), ErrorCode(0)), |
| 1214 |
| 1215 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 7, |
| 1216 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1141 0x80000000, | 1217 0x80000000, |
| 1142 ErrorCode(1), ErrorCode(0)), | 1218 ErrorCode(1), ErrorCode(0)), |
| 1143 | 1219 |
| 1144 // All the following tests don't really make much sense on 32bit | 1220 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 8, |
| 1145 // systems. They will always evaluate as false. | 1221 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1146 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 4, | |
| 1147 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
| 1148 0x0, | |
| 1149 ErrorCode(1), ErrorCode(0)), | |
| 1150 | |
| 1151 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 5, | |
| 1152 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
| 1153 0x1, | |
| 1154 ErrorCode(1), ErrorCode(0)), | |
| 1155 | |
| 1156 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 6, | |
| 1157 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
| 1158 0x3, | |
| 1159 ErrorCode(1), ErrorCode(0)), | |
| 1160 | |
| 1161 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 7, | |
| 1162 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
| 1163 0x80000000, | |
| 1164 ErrorCode(1), ErrorCode(0)), | |
| 1165 | |
| 1166 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 8, | |
| 1167 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | |
| 1168 0x100000000ULL, | 1222 0x100000000ULL, |
| 1169 ErrorCode(1), ErrorCode(0)), | 1223 ErrorCode(1), ErrorCode(0)), |
| 1170 | 1224 |
| 1171 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 9, | 1225 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 9, |
| 1172 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | 1226 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1173 0x300000000ULL, | 1227 0x300000000ULL, |
| 1174 ErrorCode(1), ErrorCode(0)), | 1228 ErrorCode(1), ErrorCode(0)), |
| 1175 | 1229 |
| 1176 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, | 1230 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, |
| 1177 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | 1231 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1178 0x100000001ULL, | 1232 0x100000001ULL, |
| 1179 ErrorCode(1), ErrorCode(0)), | 1233 ErrorCode(1), ErrorCode(0)), |
| 1180 | 1234 |
| 1181 Sandbox::Kill("Invalid test case number")))))))))))); | 1235 sandbox->Kill("Invalid test case number")))))))))))); |
| 1182 } else { | 1236 } else { |
| 1183 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1237 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1184 } | 1238 } |
| 1185 } | 1239 } |
| 1186 | 1240 |
| 1187 // Define a macro that performs tests using our test policy. | 1241 // Define a macro that performs tests using our test policy. |
| 1188 // NOTE: Not all of the arguments in this macro are actually used! | 1242 // NOTE: Not all of the arguments in this macro are actually used! |
| 1189 // They are here just to serve as documentation of the conditions | 1243 // They are here just to serve as documentation of the conditions |
| 1190 // implemented in the test policy. | 1244 // implemented in the test policy. |
| 1191 // Most notably, "op" and "mask" are unused by the macro. If you want | 1245 // Most notably, "op" and "mask" are unused by the macro. If you want |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 | 1358 |
| 1305 // 64bit test: all of 0x100000001 | 1359 // 64bit test: all of 0x100000001 |
| 1306 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1360 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1307 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1361 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1308 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1362 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1309 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1363 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
| 1310 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1364 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1311 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1365 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
| 1312 } | 1366 } |
| 1313 | 1367 |
| 1314 ErrorCode AnyBitTestPolicy(int sysno, void *) { | 1368 ErrorCode AnyBitTestPolicy(Sandbox *sandbox, int sysno, void *) { |
| 1315 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of | 1369 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of |
| 1316 // different bitmasks. We try to find bitmasks that could conceivably | 1370 // different bitmasks. We try to find bitmasks that could conceivably |
| 1317 // touch corner cases. | 1371 // touch corner cases. |
| 1318 // For all of these tests, we override the uname(). We can make use with | 1372 // For all of these tests, we override the uname(). We can make use with |
| 1319 // a single system call number, as we use the first system call argument to | 1373 // a single system call number, as we use the first system call argument to |
| 1320 // select the different bit masks that we want to test against. | 1374 // select the different bit masks that we want to test against. |
| 1321 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1375 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1322 // FIXME: we should really not have to do that in a trivial policy | 1376 // FIXME: we should really not have to do that in a trivial policy |
| 1323 return ErrorCode(ENOSYS); | 1377 return ErrorCode(ENOSYS); |
| 1324 } else if (sysno == __NR_uname) { | 1378 } else if (sysno == __NR_uname) { |
| 1325 return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1379 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
| 1326 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1380 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1327 0x0, | 1381 0x0, |
| 1328 ErrorCode(1), ErrorCode(0)), | 1382 ErrorCode(1), ErrorCode(0)), |
| 1329 | 1383 |
| 1330 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, | 1384 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, |
| 1331 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1385 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1332 0x1, | 1386 0x1, |
| 1333 ErrorCode(1), ErrorCode(0)), | 1387 ErrorCode(1), ErrorCode(0)), |
| 1334 | 1388 |
| 1335 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 2, | 1389 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 2, |
| 1336 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1390 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1337 0x3, | 1391 0x3, |
| 1338 ErrorCode(1), ErrorCode(0)), | 1392 ErrorCode(1), ErrorCode(0)), |
| 1339 | 1393 |
| 1340 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 3, | 1394 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 3, |
| 1341 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1395 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1342 0x80000000, | 1396 0x80000000, |
| 1343 ErrorCode(1), ErrorCode(0)), | 1397 ErrorCode(1), ErrorCode(0)), |
| 1344 | 1398 |
| 1345 // All the following tests don't really make much sense on 32bit | 1399 // All the following tests don't really make much sense on 32bit |
| 1346 // systems. They will always evaluate as false. | 1400 // systems. They will always evaluate as false. |
| 1347 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 4, | 1401 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 4, |
| 1348 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1402 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1349 0x0, | 1403 0x0, |
| 1350 ErrorCode(1), ErrorCode(0)), | 1404 ErrorCode(1), ErrorCode(0)), |
| 1351 | 1405 |
| 1352 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 5, | 1406 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 5, |
| 1353 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1407 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1354 0x1, | 1408 0x1, |
| 1355 ErrorCode(1), ErrorCode(0)), | 1409 ErrorCode(1), ErrorCode(0)), |
| 1356 | 1410 |
| 1357 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 6, | 1411 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 6, |
| 1358 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1412 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1359 0x3, | 1413 0x3, |
| 1360 ErrorCode(1), ErrorCode(0)), | 1414 ErrorCode(1), ErrorCode(0)), |
| 1361 | 1415 |
| 1362 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 7, | 1416 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 7, |
| 1363 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1417 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1364 0x80000000, | 1418 0x80000000, |
| 1365 ErrorCode(1), ErrorCode(0)), | 1419 ErrorCode(1), ErrorCode(0)), |
| 1366 | 1420 |
| 1367 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 8, | 1421 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 8, |
| 1368 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1422 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1369 0x100000000ULL, | 1423 0x100000000ULL, |
| 1370 ErrorCode(1), ErrorCode(0)), | 1424 ErrorCode(1), ErrorCode(0)), |
| 1371 | 1425 |
| 1372 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 9, | 1426 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 9, |
| 1373 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1427 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1374 0x300000000ULL, | 1428 0x300000000ULL, |
| 1375 ErrorCode(1), ErrorCode(0)), | 1429 ErrorCode(1), ErrorCode(0)), |
| 1376 | 1430 |
| 1377 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, | 1431 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, |
| 1378 Sandbox::Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1432 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1379 0x100000001ULL, | 1433 0x100000001ULL, |
| 1380 ErrorCode(1), ErrorCode(0)), | 1434 ErrorCode(1), ErrorCode(0)), |
| 1381 | 1435 |
| 1382 Sandbox::Kill("Invalid test case number")))))))))))); | 1436 sandbox->Kill("Invalid test case number")))))))))))); |
| 1383 } else { | 1437 } else { |
| 1384 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1438 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1385 } | 1439 } |
| 1386 } | 1440 } |
| 1387 | 1441 |
| 1388 BPF_TEST(SandboxBpf, AnyBitTests, AnyBitTestPolicy) { | 1442 BPF_TEST(SandboxBpf, AnyBitTests, AnyBitTestPolicy) { |
| 1389 // 32bit test: any of 0x0 (should always be false) | 1443 // 32bit test: any of 0x0 (should always be false) |
| 1390 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); | 1444 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); |
| 1391 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); | 1445 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); |
| 1392 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); | 1446 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1505 "%s\n", | 1559 "%s\n", |
| 1506 args.nr, | 1560 args.nr, |
| 1507 (long long)args.args[0], (long long)args.args[1], | 1561 (long long)args.args[0], (long long)args.args[1], |
| 1508 (long long)args.args[2], (long long)args.args[3], | 1562 (long long)args.args[2], (long long)args.args[3], |
| 1509 (long long)args.args[4], (long long)args.args[5], | 1563 (long long)args.args[4], (long long)args.args[5], |
| 1510 msg); | 1564 msg); |
| 1511 } | 1565 } |
| 1512 return -EPERM; | 1566 return -EPERM; |
| 1513 } | 1567 } |
| 1514 | 1568 |
| 1515 ErrorCode PthreadPolicyEquality(int sysno, void *aux) { | 1569 ErrorCode PthreadPolicyEquality(Sandbox *sandbox, int sysno, void *aux) { |
| 1516 // This policy allows creating threads with pthread_create(). But it | 1570 // This policy allows creating threads with pthread_create(). But it |
| 1517 // doesn't allow any other uses of clone(). Most notably, it does not | 1571 // doesn't allow any other uses of clone(). Most notably, it does not |
| 1518 // allow callers to implement fork() or vfork() by passing suitable flags | 1572 // allow callers to implement fork() or vfork() by passing suitable flags |
| 1519 // to the clone() system call. | 1573 // to the clone() system call. |
| 1520 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1574 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1521 // FIXME: we should really not have to do that in a trivial policy | 1575 // FIXME: we should really not have to do that in a trivial policy |
| 1522 return ErrorCode(ENOSYS); | 1576 return ErrorCode(ENOSYS); |
| 1523 } else if (sysno == __NR_clone) { | 1577 } else if (sysno == __NR_clone) { |
| 1524 // We have seen two different valid combinations of flags. Glibc | 1578 // We have seen two different valid combinations of flags. Glibc |
| 1525 // uses the more modern flags, sets the TLS from the call to clone(), and | 1579 // uses the more modern flags, sets the TLS from the call to clone(), and |
| 1526 // uses futexes to monitor threads. Android's C run-time library, doesn't | 1580 // uses futexes to monitor threads. Android's C run-time library, doesn't |
| 1527 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. | 1581 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
| 1528 // The following policy is very strict. It only allows the exact masks | 1582 // The following policy is very strict. It only allows the exact masks |
| 1529 // that we have seen in known implementations. It is probably somewhat | 1583 // that we have seen in known implementations. It is probably somewhat |
| 1530 // stricter than what we would want to do. | 1584 // stricter than what we would want to do. |
| 1531 return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1585 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 1532 CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| | 1586 CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| |
| 1533 CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS| | 1587 CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS| |
| 1534 CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, | 1588 CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, |
| 1535 ErrorCode(ErrorCode::ERR_ALLOWED), | 1589 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1536 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1590 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 1537 CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| | 1591 CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| |
| 1538 CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED, | 1592 CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED, |
| 1539 ErrorCode(ErrorCode::ERR_ALLOWED), | 1593 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1540 Sandbox::Trap(PthreadTrapHandler, aux))); | 1594 sandbox->Trap(PthreadTrapHandler, aux))); |
| 1541 | |
| 1542 } else { | 1595 } else { |
| 1543 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1596 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1544 } | 1597 } |
| 1545 } | 1598 } |
| 1546 | 1599 |
| 1547 ErrorCode PthreadPolicyBitMask(int sysno, void *aux) { | 1600 ErrorCode PthreadPolicyBitMask(Sandbox *sandbox, int sysno, void *aux) { |
| 1548 // This policy allows creating threads with pthread_create(). But it | 1601 // This policy allows creating threads with pthread_create(). But it |
| 1549 // doesn't allow any other uses of clone(). Most notably, it does not | 1602 // doesn't allow any other uses of clone(). Most notably, it does not |
| 1550 // allow callers to implement fork() or vfork() by passing suitable flags | 1603 // allow callers to implement fork() or vfork() by passing suitable flags |
| 1551 // to the clone() system call. | 1604 // to the clone() system call. |
| 1552 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1605 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
| 1553 // FIXME: we should really not have to do that in a trivial policy | 1606 // FIXME: we should really not have to do that in a trivial policy |
| 1554 return ErrorCode(ENOSYS); | 1607 return ErrorCode(ENOSYS); |
| 1555 } else if (sysno == __NR_clone) { | 1608 } else if (sysno == __NR_clone) { |
| 1556 // We have seen two different valid combinations of flags. Glibc | 1609 // We have seen two different valid combinations of flags. Glibc |
| 1557 // uses the more modern flags, sets the TLS from the call to clone(), and | 1610 // uses the more modern flags, sets the TLS from the call to clone(), and |
| 1558 // uses futexes to monitor threads. Android's C run-time library, doesn't | 1611 // uses futexes to monitor threads. Android's C run-time library, doesn't |
| 1559 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. | 1612 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
| 1560 // The following policy allows for either combination of flags, but it | 1613 // The following policy allows for either combination of flags, but it |
| 1561 // is generally a little more conservative than strictly necessary. We | 1614 // is generally a little more conservative than strictly necessary. We |
| 1562 // err on the side of rather safe than sorry. | 1615 // err on the side of rather safe than sorry. |
| 1563 // Very noticeably though, we disallow fork() (which is often just a | 1616 // Very noticeably though, we disallow fork() (which is often just a |
| 1564 // wrapper around clone()). | 1617 // wrapper around clone()). |
| 1565 return Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1618 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1566 ~uint32(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| | 1619 ~uint32(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| |
| 1567 CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS| | 1620 CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS| |
| 1568 CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID| | 1621 CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID| |
| 1569 CLONE_DETACHED), | 1622 CLONE_DETACHED), |
| 1570 Sandbox::Trap(PthreadTrapHandler, | 1623 sandbox->Trap(PthreadTrapHandler, |
| 1571 "Unexpected CLONE_XXX flag found"), | 1624 "Unexpected CLONE_XXX flag found"), |
| 1572 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1625 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1573 CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| | 1626 CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND| |
| 1574 CLONE_THREAD|CLONE_SYSVSEM, | 1627 CLONE_THREAD|CLONE_SYSVSEM, |
| 1575 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1628 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1576 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, | 1629 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, |
| 1577 ErrorCode(ErrorCode::ERR_ALLOWED), | 1630 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1578 Sandbox::Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1631 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1579 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, | 1632 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, |
| 1580 Sandbox::Trap(PthreadTrapHandler, | 1633 sandbox->Trap(PthreadTrapHandler, |
| 1581 "Must set either all or none of the TLS" | 1634 "Must set either all or none of the TLS" |
| 1582 " and futex bits in call to clone()"), | 1635 " and futex bits in call to clone()"), |
| 1583 ErrorCode(ErrorCode::ERR_ALLOWED))), | 1636 ErrorCode(ErrorCode::ERR_ALLOWED))), |
| 1584 Sandbox::Trap(PthreadTrapHandler, | 1637 sandbox->Trap(PthreadTrapHandler, |
| 1585 "Missing mandatory CLONE_XXX flags " | 1638 "Missing mandatory CLONE_XXX flags " |
| 1586 "when creating new thread"))); | 1639 "when creating new thread"))); |
| 1587 } else { | 1640 } else { |
| 1588 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1641 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1589 } | 1642 } |
| 1590 } | 1643 } |
| 1591 | 1644 |
| 1592 static void *ThreadFnc(void *arg) { | 1645 static void *ThreadFnc(void *arg) { |
| 1593 ++*reinterpret_cast<int *>(arg); | 1646 ++*reinterpret_cast<int *>(arg); |
| 1594 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); | 1647 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1628 | 1681 |
| 1629 BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) { | 1682 BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) { |
| 1630 PthreadTest(); | 1683 PthreadTest(); |
| 1631 } | 1684 } |
| 1632 | 1685 |
| 1633 BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) { | 1686 BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) { |
| 1634 PthreadTest(); | 1687 PthreadTest(); |
| 1635 } | 1688 } |
| 1636 | 1689 |
| 1637 } // namespace | 1690 } // namespace |
| OLD | NEW |