| 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 BPF_ASSERT_EQ(2, pid); | 119 BPF_ASSERT_EQ(2, pid); |
| 120 | 120 |
| 121 // N.B.: Any future call to getpid() would corrupt the stack. | 121 // N.B.: Any future call to getpid() would corrupt the stack. |
| 122 // This is OK. The SANDBOX_TEST() macro is guaranteed to | 122 // This is OK. The SANDBOX_TEST() macro is guaranteed to |
| 123 // only ever call _exit() after the test completes. | 123 // only ever call _exit() after the test completes. |
| 124 } | 124 } |
| 125 } | 125 } |
| 126 | 126 |
| 127 // A simple blacklist test | 127 // A simple blacklist test |
| 128 | 128 |
| 129 ErrorCode BlacklistNanosleepPolicy(SandboxBPF*, int sysno, void* aux) { | 129 class BlacklistNanosleepPolicy : public SandboxBPFPolicy { |
| 130 // Since no type was specified in BPF_TEST as a fourth argument, | 130 public: |
| 131 // |aux| must be NULL here. | 131 BlacklistNanosleepPolicy() {} |
| 132 BPF_ASSERT(NULL == aux); | 132 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
| 133 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 133 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 134 // FIXME: we should really not have to do that in a trivial policy | 134 switch (sysno) { |
| 135 return ErrorCode(ENOSYS); | 135 case __NR_nanosleep: |
| 136 return ErrorCode(EACCES); |
| 137 default: |
| 138 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 139 } |
| 136 } | 140 } |
| 137 | 141 |
| 138 switch (sysno) { | 142 private: |
| 139 case __NR_nanosleep: | 143 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepPolicy); |
| 140 return ErrorCode(EACCES); | 144 }; |
| 141 default: | |
| 142 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 143 } | |
| 144 } | |
| 145 | 145 |
| 146 BPF_TEST(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | 146 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { |
| 147 // nanosleep() should be denied | 147 // nanosleep() should be denied |
| 148 const struct timespec ts = {0, 0}; | 148 const struct timespec ts = {0, 0}; |
| 149 errno = 0; | 149 errno = 0; |
| 150 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 150 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| 151 BPF_ASSERT(errno == EACCES); | 151 BPF_ASSERT(errno == EACCES); |
| 152 } | 152 } |
| 153 |
| 153 // Now do a simple whitelist test | 154 // Now do a simple whitelist test |
| 154 | 155 |
| 155 ErrorCode WhitelistGetpidPolicy(SandboxBPF*, int sysno, void*) { | 156 class WhitelistGetpidPolicy : public SandboxBPFPolicy { |
| 156 switch (sysno) { | 157 public: |
| 157 case __NR_getpid: | 158 WhitelistGetpidPolicy() {} |
| 158 case __NR_exit_group: | 159 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
| 159 return ErrorCode(ErrorCode::ERR_ALLOWED); | 160 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 160 default: | 161 switch (sysno) { |
| 161 return ErrorCode(ENOMEM); | 162 case __NR_getpid: |
| 163 case __NR_exit_group: |
| 164 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 165 default: |
| 166 return ErrorCode(ENOMEM); |
| 167 } |
| 162 } | 168 } |
| 163 } | |
| 164 | 169 |
| 165 BPF_TEST(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { | 170 private: |
| 171 DISALLOW_COPY_AND_ASSIGN(WhitelistGetpidPolicy); |
| 172 }; |
| 173 |
| 174 BPF_TEST_C(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { |
| 166 // getpid() should be allowed | 175 // getpid() should be allowed |
| 167 errno = 0; | 176 errno = 0; |
| 168 BPF_ASSERT(syscall(__NR_getpid) > 0); | 177 BPF_ASSERT(syscall(__NR_getpid) > 0); |
| 169 BPF_ASSERT(errno == 0); | 178 BPF_ASSERT(errno == 0); |
| 170 | 179 |
| 171 // getpgid() should be denied | 180 // getpgid() should be denied |
| 172 BPF_ASSERT(getpgid(0) == -1); | 181 BPF_ASSERT(getpgid(0) == -1); |
| 173 BPF_ASSERT(errno == ENOMEM); | 182 BPF_ASSERT(errno == ENOMEM); |
| 174 } | 183 } |
| 175 | 184 |
| 176 // A simple blacklist policy, with a SIGSYS handler | 185 // A simple blacklist policy, with a SIGSYS handler |
| 177 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { | 186 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { |
| 178 // We also check that the auxiliary data is correct | 187 // We also check that the auxiliary data is correct |
| 179 SANDBOX_ASSERT(aux); | 188 SANDBOX_ASSERT(aux); |
| 180 *(static_cast<int*>(aux)) = kExpectedReturnValue; | 189 *(static_cast<int*>(aux)) = kExpectedReturnValue; |
| 181 return -ENOMEM; | 190 return -ENOMEM; |
| 182 } | 191 } |
| 183 | 192 |
| 184 ErrorCode BlacklistNanosleepPolicySigsys(SandboxBPF* sandbox, | 193 ErrorCode BlacklistNanosleepPolicySigsys(SandboxBPF* sandbox, |
| 185 int sysno, | 194 int sysno, |
| 186 int* aux) { | 195 int* aux) { |
| 187 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 196 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 188 // FIXME: we should really not have to do that in a trivial policy | |
| 189 return ErrorCode(ENOSYS); | |
| 190 } | |
| 191 | |
| 192 switch (sysno) { | 197 switch (sysno) { |
| 193 case __NR_nanosleep: | 198 case __NR_nanosleep: |
| 194 return sandbox->Trap(EnomemHandler, aux); | 199 return sandbox->Trap(EnomemHandler, aux); |
| 195 default: | 200 default: |
| 196 return ErrorCode(ErrorCode::ERR_ALLOWED); | 201 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 197 } | 202 } |
| 198 } | 203 } |
| 199 | 204 |
| 200 BPF_TEST(SandboxBPF, | 205 BPF_TEST(SandboxBPF, |
| 201 BasicBlacklistWithSigsys, | 206 BasicBlacklistWithSigsys, |
| 202 BlacklistNanosleepPolicySigsys, | 207 BlacklistNanosleepPolicySigsys, |
| 203 int /* (*BPF_AUX) */) { | 208 int /* (*BPF_AUX) */) { |
| 204 // getpid() should work properly | 209 // getpid() should work properly |
| 205 errno = 0; | 210 errno = 0; |
| 206 BPF_ASSERT(syscall(__NR_getpid) > 0); | 211 BPF_ASSERT(syscall(__NR_getpid) > 0); |
| 207 BPF_ASSERT(errno == 0); | 212 BPF_ASSERT(errno == 0); |
| 208 | 213 |
| 209 // Our Auxiliary Data, should be reset by the signal handler | 214 // Our Auxiliary Data, should be reset by the signal handler |
| 210 *BPF_AUX = -1; | 215 *BPF_AUX = -1; |
| 211 const struct timespec ts = {0, 0}; | 216 const struct timespec ts = {0, 0}; |
| 212 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 217 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| 213 BPF_ASSERT(errno == ENOMEM); | 218 BPF_ASSERT(errno == ENOMEM); |
| 214 | 219 |
| 215 // We expect the signal handler to modify AuxData | 220 // We expect the signal handler to modify AuxData |
| 216 BPF_ASSERT(*BPF_AUX == kExpectedReturnValue); | 221 BPF_ASSERT(*BPF_AUX == kExpectedReturnValue); |
| 217 } | 222 } |
| 218 | 223 |
| 219 // A simple test that verifies we can return arbitrary errno values. | 224 // A simple test that verifies we can return arbitrary errno values. |
| 220 | 225 |
| 221 ErrorCode ErrnoTestPolicy(SandboxBPF*, int sysno, void*) { | 226 class ErrnoTestPolicy : public SandboxBPFPolicy { |
| 222 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 227 public: |
| 223 // FIXME: we should really not have to do that in a trivial policy | 228 ErrnoTestPolicy() {} |
| 224 return ErrorCode(ENOSYS); | 229 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE; |
| 225 } | |
| 226 | 230 |
| 231 private: |
| 232 DISALLOW_COPY_AND_ASSIGN(ErrnoTestPolicy); |
| 233 }; |
| 234 |
| 235 ErrorCode ErrnoTestPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const { |
| 236 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 227 switch (sysno) { | 237 switch (sysno) { |
| 228 #if defined(ANDROID) | 238 #if defined(ANDROID) |
| 229 case __NR_dup3: // dup2 is a wrapper of dup3 in android | 239 case __NR_dup3: // dup2 is a wrapper of dup3 in android |
| 230 #else | 240 #else |
| 231 case __NR_dup2: | 241 case __NR_dup2: |
| 232 #endif | 242 #endif |
| 233 // Pretend that dup2() worked, but don't actually do anything. | 243 // Pretend that dup2() worked, but don't actually do anything. |
| 234 return ErrorCode(0); | 244 return ErrorCode(0); |
| 235 case __NR_setuid: | 245 case __NR_setuid: |
| 236 #if defined(__NR_setuid32) | 246 #if defined(__NR_setuid32) |
| 237 case __NR_setuid32: | 247 case __NR_setuid32: |
| 238 #endif | 248 #endif |
| 239 // Return errno = 1. | 249 // Return errno = 1. |
| 240 return ErrorCode(1); | 250 return ErrorCode(1); |
| 241 case __NR_setgid: | 251 case __NR_setgid: |
| 242 #if defined(__NR_setgid32) | 252 #if defined(__NR_setgid32) |
| 243 case __NR_setgid32: | 253 case __NR_setgid32: |
| 244 #endif | 254 #endif |
| 245 // Return maximum errno value (typically 4095). | 255 // Return maximum errno value (typically 4095). |
| 246 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); | 256 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); |
| 247 case __NR_uname: | 257 case __NR_uname: |
| 248 // Return errno = 42; | 258 // Return errno = 42; |
| 249 return ErrorCode(42); | 259 return ErrorCode(42); |
| 250 default: | 260 default: |
| 251 return ErrorCode(ErrorCode::ERR_ALLOWED); | 261 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 252 } | 262 } |
| 253 } | 263 } |
| 254 | 264 |
| 255 BPF_TEST(SandboxBPF, ErrnoTest, ErrnoTestPolicy) { | 265 BPF_TEST_C(SandboxBPF, ErrnoTest, ErrnoTestPolicy) { |
| 256 // Verify that dup2() returns success, but doesn't actually run. | 266 // Verify that dup2() returns success, but doesn't actually run. |
| 257 int fds[4]; | 267 int fds[4]; |
| 258 BPF_ASSERT(pipe(fds) == 0); | 268 BPF_ASSERT(pipe(fds) == 0); |
| 259 BPF_ASSERT(pipe(fds + 2) == 0); | 269 BPF_ASSERT(pipe(fds + 2) == 0); |
| 260 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); | 270 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); |
| 261 char buf[1] = {}; | 271 char buf[1] = {}; |
| 262 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); | 272 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); |
| 263 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); | 273 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); |
| 264 BPF_ASSERT(read(fds[0], buf, 1) == 1); | 274 BPF_ASSERT(read(fds[0], buf, 1) == 1); |
| 265 | 275 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 // We try to make sure we exercise optimizations in the BPF compiler. We make | 380 // We try to make sure we exercise optimizations in the BPF compiler. We make |
| 371 // sure that the compiler can have an opportunity to coalesce syscalls with | 381 // sure that the compiler can have an opportunity to coalesce syscalls with |
| 372 // contiguous numbers and we also make sure that disjoint sets can return the | 382 // contiguous numbers and we also make sure that disjoint sets can return the |
| 373 // same errno. | 383 // same errno. |
| 374 int SysnoToRandomErrno(int sysno) { | 384 int SysnoToRandomErrno(int sysno) { |
| 375 // Small contiguous sets of 3 system calls return an errno equal to the | 385 // Small contiguous sets of 3 system calls return an errno equal to the |
| 376 // index of that set + 1 (so that we never return a NUL errno). | 386 // index of that set + 1 (so that we never return a NUL errno). |
| 377 return ((sysno & ~3) >> 2) % 29 + 1; | 387 return ((sysno & ~3) >> 2) % 29 + 1; |
| 378 } | 388 } |
| 379 | 389 |
| 380 ErrorCode SyntheticPolicy(SandboxBPF*, int sysno, void*) { | 390 class SyntheticPolicy : public SandboxBPFPolicy { |
| 381 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 391 public: |
| 382 // FIXME: we should really not have to do that in a trivial policy | 392 SyntheticPolicy() {} |
| 383 return ErrorCode(ENOSYS); | 393 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
| 394 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 395 if (sysno == __NR_exit_group || sysno == __NR_write) { |
| 396 // exit_group() is special, we really need it to work. |
| 397 // write() is needed for BPF_ASSERT() to report a useful error message. |
| 398 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 399 } |
| 400 return ErrorCode(SysnoToRandomErrno(sysno)); |
| 384 } | 401 } |
| 385 | 402 |
| 386 if (sysno == __NR_exit_group || sysno == __NR_write) { | 403 private: |
| 387 // exit_group() is special, we really need it to work. | 404 DISALLOW_COPY_AND_ASSIGN(SyntheticPolicy); |
| 388 // write() is needed for BPF_ASSERT() to report a useful error message. | 405 }; |
| 389 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 390 } else { | |
| 391 return ErrorCode(SysnoToRandomErrno(sysno)); | |
| 392 } | |
| 393 } | |
| 394 | 406 |
| 395 BPF_TEST(SandboxBPF, SyntheticPolicy, SyntheticPolicy) { | 407 BPF_TEST_C(SandboxBPF, SyntheticPolicy, SyntheticPolicy) { |
| 396 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int | 408 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int |
| 397 // overflow. | 409 // overflow. |
| 398 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= | 410 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= |
| 399 static_cast<int>(MAX_PUBLIC_SYSCALL)); | 411 static_cast<int>(MAX_PUBLIC_SYSCALL)); |
| 400 | 412 |
| 401 for (int syscall_number = static_cast<int>(MIN_SYSCALL); | 413 for (int syscall_number = static_cast<int>(MIN_SYSCALL); |
| 402 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); | 414 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); |
| 403 ++syscall_number) { | 415 ++syscall_number) { |
| 404 if (syscall_number == __NR_exit_group || syscall_number == __NR_write) { | 416 if (syscall_number == __NR_exit_group || syscall_number == __NR_write) { |
| 405 // exit_group() is special | 417 // exit_group() is special |
| (...skipping 13 matching lines...) Expand all Loading... |
| 419 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). | 431 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). |
| 420 int ArmPrivateSysnoToErrno(int sysno) { | 432 int ArmPrivateSysnoToErrno(int sysno) { |
| 421 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && | 433 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && |
| 422 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 434 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
| 423 return (sysno - MIN_PRIVATE_SYSCALL) + 1; | 435 return (sysno - MIN_PRIVATE_SYSCALL) + 1; |
| 424 } else { | 436 } else { |
| 425 return ENOSYS; | 437 return ENOSYS; |
| 426 } | 438 } |
| 427 } | 439 } |
| 428 | 440 |
| 429 ErrorCode ArmPrivatePolicy(SandboxBPF*, int sysno, void*) { | 441 class ArmPrivatePolicy : public SandboxBPFPolicy { |
| 430 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 442 public: |
| 431 // FIXME: we should really not have to do that in a trivial policy. | 443 ArmPrivatePolicy() {} |
| 432 return ErrorCode(ENOSYS); | 444 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
| 445 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 446 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual |
| 447 // ARM private system calls. |
| 448 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && |
| 449 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
| 450 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); |
| 451 } |
| 452 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 433 } | 453 } |
| 434 | 454 |
| 435 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual | 455 private: |
| 436 // ARM private system calls. | 456 DISALLOW_COPY_AND_ASSIGN(ArmPrivatePolicy); |
| 437 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && | 457 }; |
| 438 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | |
| 439 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); | |
| 440 } else { | |
| 441 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 442 } | |
| 443 } | |
| 444 | 458 |
| 445 BPF_TEST(SandboxBPF, ArmPrivatePolicy, ArmPrivatePolicy) { | 459 BPF_TEST_C(SandboxBPF, ArmPrivatePolicy, ArmPrivatePolicy) { |
| 446 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); | 460 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); |
| 447 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); | 461 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); |
| 448 ++syscall_number) { | 462 ++syscall_number) { |
| 449 errno = 0; | 463 errno = 0; |
| 450 BPF_ASSERT(syscall(syscall_number) == -1); | 464 BPF_ASSERT(syscall(syscall_number) == -1); |
| 451 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); | 465 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); |
| 452 } | 466 } |
| 453 } | 467 } |
| 454 #endif // defined(__arm__) | 468 #endif // defined(__arm__) |
| 455 | 469 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { | 546 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { |
| 533 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { | 547 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { |
| 534 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always | 548 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always |
| 535 // return an error. But our handler allows this call. | 549 // return an error. But our handler allows this call. |
| 536 return 0; | 550 return 0; |
| 537 } else { | 551 } else { |
| 538 return SandboxBPF::ForwardSyscall(args); | 552 return SandboxBPF::ForwardSyscall(args); |
| 539 } | 553 } |
| 540 } | 554 } |
| 541 | 555 |
| 542 ErrorCode PrctlPolicy(SandboxBPF* sandbox, int sysno, void* aux) { | 556 class PrctlPolicy : public SandboxBPFPolicy { |
| 543 setenv(kSandboxDebuggingEnv, "t", 0); | 557 public: |
| 544 Die::SuppressInfoMessages(true); | 558 PrctlPolicy() {} |
| 559 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 560 int sysno) const OVERRIDE { |
| 561 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 562 setenv(kSandboxDebuggingEnv, "t", 0); |
| 563 Die::SuppressInfoMessages(true); |
| 545 | 564 |
| 546 if (sysno == __NR_prctl) { | 565 if (sysno == __NR_prctl) { |
| 547 // Handle prctl() inside an UnsafeTrap() | 566 // Handle prctl() inside an UnsafeTrap() |
| 548 return sandbox->UnsafeTrap(PrctlHandler, NULL); | 567 return sandbox->UnsafeTrap(PrctlHandler, NULL); |
| 549 } else if (SandboxBPF::IsValidSyscallNumber(sysno)) { | 568 } |
| 569 |
| 550 // Allow all other system calls. | 570 // Allow all other system calls. |
| 551 return ErrorCode(ErrorCode::ERR_ALLOWED); | 571 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 552 } else { | |
| 553 return ErrorCode(ENOSYS); | |
| 554 } | 572 } |
| 555 } | |
| 556 | 573 |
| 557 BPF_TEST(SandboxBPF, ForwardSyscall, PrctlPolicy) { | 574 private: |
| 575 DISALLOW_COPY_AND_ASSIGN(PrctlPolicy); |
| 576 }; |
| 577 |
| 578 BPF_TEST_C(SandboxBPF, ForwardSyscall, PrctlPolicy) { |
| 558 // This call should never be allowed. But our policy will intercept it and | 579 // This call should never be allowed. But our policy will intercept it and |
| 559 // let it pass successfully. | 580 // let it pass successfully. |
| 560 BPF_ASSERT( | 581 BPF_ASSERT( |
| 561 !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL)); | 582 !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL)); |
| 562 | 583 |
| 563 // Verify that the call will fail, if it makes it all the way to the kernel. | 584 // Verify that the call will fail, if it makes it all the way to the kernel. |
| 564 BPF_ASSERT( | 585 BPF_ASSERT( |
| 565 prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1); | 586 prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1); |
| 566 | 587 |
| 567 // And verify that other uses of prctl() work just fine. | 588 // And verify that other uses of prctl() work just fine. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 578 // unaffected by our policy. | 599 // unaffected by our policy. |
| 579 struct utsname uts = {}; | 600 struct utsname uts = {}; |
| 580 BPF_ASSERT(!uname(&uts)); | 601 BPF_ASSERT(!uname(&uts)); |
| 581 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); | 602 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); |
| 582 } | 603 } |
| 583 | 604 |
| 584 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { | 605 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { |
| 585 return SandboxBPF::ForwardSyscall(args); | 606 return SandboxBPF::ForwardSyscall(args); |
| 586 } | 607 } |
| 587 | 608 |
| 588 ErrorCode RedirectAllSyscallsPolicy(SandboxBPF* sandbox, int sysno, void* aux) { | 609 class RedirectAllSyscallsPolicy : public SandboxBPFPolicy { |
| 610 public: |
| 611 RedirectAllSyscallsPolicy() {} |
| 612 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 613 int sysno) const OVERRIDE; |
| 614 |
| 615 private: |
| 616 DISALLOW_COPY_AND_ASSIGN(RedirectAllSyscallsPolicy); |
| 617 }; |
| 618 |
| 619 ErrorCode RedirectAllSyscallsPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
| 620 int sysno) const { |
| 621 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 589 setenv(kSandboxDebuggingEnv, "t", 0); | 622 setenv(kSandboxDebuggingEnv, "t", 0); |
| 590 Die::SuppressInfoMessages(true); | 623 Die::SuppressInfoMessages(true); |
| 591 | 624 |
| 592 // Some system calls must always be allowed, if our policy wants to make | 625 // Some system calls must always be allowed, if our policy wants to make |
| 593 // use of UnsafeTrap() | 626 // use of UnsafeTrap() |
| 594 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn | 627 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn |
| 595 #if defined(__NR_sigprocmask) | 628 #if defined(__NR_sigprocmask) |
| 596 || | 629 || |
| 597 sysno == __NR_sigprocmask | 630 sysno == __NR_sigprocmask |
| 598 #endif | 631 #endif |
| 599 #if defined(__NR_sigreturn) | 632 #if defined(__NR_sigreturn) |
| 600 || | 633 || |
| 601 sysno == __NR_sigreturn | 634 sysno == __NR_sigreturn |
| 602 #endif | 635 #endif |
| 603 ) { | 636 ) { |
| 604 return ErrorCode(ErrorCode::ERR_ALLOWED); | 637 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 605 } else if (SandboxBPF::IsValidSyscallNumber(sysno)) { | |
| 606 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux); | |
| 607 } else { | |
| 608 return ErrorCode(ENOSYS); | |
| 609 } | 638 } |
| 639 return sandbox->UnsafeTrap(AllowRedirectedSyscall, NULL); |
| 610 } | 640 } |
| 611 | 641 |
| 612 int bus_handler_fd_ = -1; | 642 int bus_handler_fd_ = -1; |
| 613 | 643 |
| 614 void SigBusHandler(int, siginfo_t* info, void* void_context) { | 644 void SigBusHandler(int, siginfo_t* info, void* void_context) { |
| 615 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); | 645 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); |
| 616 } | 646 } |
| 617 | 647 |
| 618 BPF_TEST(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) { | 648 BPF_TEST_C(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) { |
| 619 // We use the SIGBUS bit in the signal mask as a thread-local boolean | 649 // We use the SIGBUS bit in the signal mask as a thread-local boolean |
| 620 // value in the implementation of UnsafeTrap(). This is obviously a bit | 650 // value in the implementation of UnsafeTrap(). This is obviously a bit |
| 621 // of a hack that could conceivably interfere with code that uses SIGBUS | 651 // of a hack that could conceivably interfere with code that uses SIGBUS |
| 622 // in more traditional ways. This test verifies that basic functionality | 652 // in more traditional ways. This test verifies that basic functionality |
| 623 // of SIGBUS is not impacted, but it is certainly possibly to construe | 653 // of SIGBUS is not impacted, but it is certainly possibly to construe |
| 624 // more complex uses of signals where our use of the SIGBUS mask is not | 654 // more complex uses of signals where our use of the SIGBUS mask is not |
| 625 // 100% transparent. This is expected behavior. | 655 // 100% transparent. This is expected behavior. |
| 626 int fds[2]; | 656 int fds[2]; |
| 627 BPF_ASSERT(pipe(fds) == 0); | 657 BPF_ASSERT(pipe(fds) == 0); |
| 628 bus_handler_fd_ = fds[1]; | 658 bus_handler_fd_ = fds[1]; |
| 629 struct sigaction sa = {}; | 659 struct sigaction sa = {}; |
| 630 sa.sa_sigaction = SigBusHandler; | 660 sa.sa_sigaction = SigBusHandler; |
| 631 sa.sa_flags = SA_SIGINFO; | 661 sa.sa_flags = SA_SIGINFO; |
| 632 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); | 662 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); |
| 633 raise(SIGBUS); | 663 raise(SIGBUS); |
| 634 char c = '\000'; | 664 char c = '\000'; |
| 635 BPF_ASSERT(read(fds[0], &c, 1) == 1); | 665 BPF_ASSERT(read(fds[0], &c, 1) == 1); |
| 636 BPF_ASSERT(close(fds[0]) == 0); | 666 BPF_ASSERT(close(fds[0]) == 0); |
| 637 BPF_ASSERT(close(fds[1]) == 0); | 667 BPF_ASSERT(close(fds[1]) == 0); |
| 638 BPF_ASSERT(c == 0x55); | 668 BPF_ASSERT(c == 0x55); |
| 639 } | 669 } |
| 640 | 670 |
| 641 BPF_TEST(SandboxBPF, SigMask, RedirectAllSyscallsPolicy) { | 671 BPF_TEST_C(SandboxBPF, SigMask, RedirectAllSyscallsPolicy) { |
| 642 // Signal masks are potentially tricky to handle. For instance, if we | 672 // Signal masks are potentially tricky to handle. For instance, if we |
| 643 // ever tried to update them from inside a Trap() or UnsafeTrap() handler, | 673 // ever tried to update them from inside a Trap() or UnsafeTrap() handler, |
| 644 // the call to sigreturn() at the end of the signal handler would undo | 674 // the call to sigreturn() at the end of the signal handler would undo |
| 645 // all of our efforts. So, it makes sense to test that sigprocmask() | 675 // all of our efforts. So, it makes sense to test that sigprocmask() |
| 646 // works, even if we have a policy in place that makes use of UnsafeTrap(). | 676 // works, even if we have a policy in place that makes use of UnsafeTrap(). |
| 647 // In practice, this works because we force sigprocmask() to be handled | 677 // In practice, this works because we force sigprocmask() to be handled |
| 648 // entirely in the kernel. | 678 // entirely in the kernel. |
| 649 sigset_t mask0, mask1, mask2; | 679 sigset_t mask0, mask1, mask2; |
| 650 | 680 |
| 651 // Call sigprocmask() to verify that SIGUSR2 wasn't blocked, if we didn't | 681 // Call sigprocmask() to verify that SIGUSR2 wasn't blocked, if we didn't |
| 652 // change the mask (it shouldn't have been, as it isn't blocked by default | 682 // change the mask (it shouldn't have been, as it isn't blocked by default |
| 653 // in POSIX). | 683 // in POSIX). |
| 654 // | 684 // |
| 655 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. | 685 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. |
| 656 sigemptyset(&mask0); | 686 sigemptyset(&mask0); |
| 657 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); | 687 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); |
| 658 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); | 688 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); |
| 659 | 689 |
| 660 // Try again, and this time we verify that we can block it. This | 690 // Try again, and this time we verify that we can block it. This |
| 661 // requires a second call to sigprocmask(). | 691 // requires a second call to sigprocmask(). |
| 662 sigaddset(&mask0, SIGUSR2); | 692 sigaddset(&mask0, SIGUSR2); |
| 663 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); | 693 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); |
| 664 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); | 694 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); |
| 665 BPF_ASSERT(sigismember(&mask2, SIGUSR2)); | 695 BPF_ASSERT(sigismember(&mask2, SIGUSR2)); |
| 666 } | 696 } |
| 667 | 697 |
| 668 BPF_TEST(SandboxBPF, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { | 698 BPF_TEST_C(SandboxBPF, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { |
| 669 // An UnsafeTrap() (or for that matter, a Trap()) has to report error | 699 // An UnsafeTrap() (or for that matter, a Trap()) has to report error |
| 670 // conditions by returning an exit code in the range -1..-4096. This | 700 // conditions by returning an exit code in the range -1..-4096. This |
| 671 // should happen automatically if using ForwardSyscall(). If the TrapFnc() | 701 // should happen automatically if using ForwardSyscall(). If the TrapFnc() |
| 672 // uses some other method to make system calls, then it is responsible | 702 // uses some other method to make system calls, then it is responsible |
| 673 // for computing the correct return code. | 703 // for computing the correct return code. |
| 674 // This test verifies that ForwardSyscall() does the correct thing. | 704 // This test verifies that ForwardSyscall() does the correct thing. |
| 675 | 705 |
| 676 // The glibc system wrapper will ultimately set errno for us. So, from normal | 706 // The glibc system wrapper will ultimately set errno for us. So, from normal |
| 677 // userspace, all of this should be completely transparent. | 707 // userspace, all of this should be completely transparent. |
| 678 errno = 0; | 708 errno = 0; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 int cpu_info_access = access("/proc/cpuinfo", R_OK); | 842 int cpu_info_access = access("/proc/cpuinfo", R_OK); |
| 813 BPF_ASSERT(cpu_info_access == 0); | 843 BPF_ASSERT(cpu_info_access == 0); |
| 814 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); | 844 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); |
| 815 BPF_ASSERT(cpu_info_fd >= 0); | 845 BPF_ASSERT(cpu_info_fd >= 0); |
| 816 char buf[1024]; | 846 char buf[1024]; |
| 817 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); | 847 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); |
| 818 } | 848 } |
| 819 | 849 |
| 820 // Simple test demonstrating how to use SandboxBPF::Cond() | 850 // Simple test demonstrating how to use SandboxBPF::Cond() |
| 821 | 851 |
| 822 ErrorCode SimpleCondTestPolicy(SandboxBPF* sandbox, int sysno, void*) { | 852 class SimpleCondTestPolicy : public SandboxBPFPolicy { |
| 823 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 853 public: |
| 824 // FIXME: we should really not have to do that in a trivial policy | 854 SimpleCondTestPolicy() {} |
| 825 return ErrorCode(ENOSYS); | 855 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 826 } | 856 int sysno) const OVERRIDE; |
| 857 |
| 858 private: |
| 859 DISALLOW_COPY_AND_ASSIGN(SimpleCondTestPolicy); |
| 860 }; |
| 861 |
| 862 ErrorCode SimpleCondTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
| 863 int sysno) const { |
| 864 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 827 | 865 |
| 828 // We deliberately return unusual errno values upon failure, so that we | 866 // We deliberately return unusual errno values upon failure, so that we |
| 829 // can uniquely test for these values. In a "real" policy, you would want | 867 // can uniquely test for these values. In a "real" policy, you would want |
| 830 // to return more traditional values. | 868 // to return more traditional values. |
| 831 switch (sysno) { | 869 switch (sysno) { |
| 832 #if defined(ANDROID) | 870 #if defined(ANDROID) |
| 833 case __NR_openat: // open is a wrapper of openat in android | 871 case __NR_openat: // open is a wrapper of openat in android |
| 834 // Allow opening files for reading, but don't allow writing. | 872 // Allow opening files for reading, but don't allow writing. |
| 835 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); | 873 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); |
| 836 return sandbox->Cond(2, | 874 return sandbox->Cond(2, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 862 ErrorCode::TP_32BIT, | 900 ErrorCode::TP_32BIT, |
| 863 ErrorCode::OP_EQUAL, | 901 ErrorCode::OP_EQUAL, |
| 864 PR_GET_DUMPABLE, | 902 PR_GET_DUMPABLE, |
| 865 ErrorCode(ErrorCode::ERR_ALLOWED), | 903 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 866 ErrorCode(ENOMEM))); | 904 ErrorCode(ENOMEM))); |
| 867 default: | 905 default: |
| 868 return ErrorCode(ErrorCode::ERR_ALLOWED); | 906 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 869 } | 907 } |
| 870 } | 908 } |
| 871 | 909 |
| 872 BPF_TEST(SandboxBPF, SimpleCondTest, SimpleCondTestPolicy) { | 910 BPF_TEST_C(SandboxBPF, SimpleCondTest, SimpleCondTestPolicy) { |
| 873 int fd; | 911 int fd; |
| 874 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); | 912 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); |
| 875 BPF_ASSERT(errno == EROFS); | 913 BPF_ASSERT(errno == EROFS); |
| 876 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); | 914 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); |
| 877 close(fd); | 915 close(fd); |
| 878 | 916 |
| 879 int ret; | 917 int ret; |
| 880 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); | 918 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); |
| 881 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0); | 919 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0); |
| 882 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); | 920 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 return aux->Policy(sandbox, sysno); | 1229 return aux->Policy(sandbox, sysno); |
| 1192 } | 1230 } |
| 1193 | 1231 |
| 1194 BPF_TEST(SandboxBPF, | 1232 BPF_TEST(SandboxBPF, |
| 1195 EqualityTests, | 1233 EqualityTests, |
| 1196 EqualityStressTestPolicy, | 1234 EqualityStressTestPolicy, |
| 1197 EqualityStressTest /* (*BPF_AUX) */) { | 1235 EqualityStressTest /* (*BPF_AUX) */) { |
| 1198 BPF_AUX->VerifyFilter(); | 1236 BPF_AUX->VerifyFilter(); |
| 1199 } | 1237 } |
| 1200 | 1238 |
| 1201 ErrorCode EqualityArgumentWidthPolicy(SandboxBPF* sandbox, int sysno, void*) { | 1239 class EqualityArgumentWidthPolicy : public SandboxBPFPolicy { |
| 1202 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1240 public: |
| 1203 // FIXME: we should really not have to do that in a trivial policy | 1241 EqualityArgumentWidthPolicy() {} |
| 1204 return ErrorCode(ENOSYS); | 1242 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 1205 } else if (sysno == __NR_uname) { | 1243 int sysno) const OVERRIDE; |
| 1244 |
| 1245 private: |
| 1246 DISALLOW_COPY_AND_ASSIGN(EqualityArgumentWidthPolicy); |
| 1247 }; |
| 1248 |
| 1249 ErrorCode EqualityArgumentWidthPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
| 1250 int sysno) const { |
| 1251 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 1252 if (sysno == __NR_uname) { |
| 1206 return sandbox->Cond( | 1253 return sandbox->Cond( |
| 1207 0, | 1254 0, |
| 1208 ErrorCode::TP_32BIT, | 1255 ErrorCode::TP_32BIT, |
| 1209 ErrorCode::OP_EQUAL, | 1256 ErrorCode::OP_EQUAL, |
| 1210 0, | 1257 0, |
| 1211 sandbox->Cond(1, | 1258 sandbox->Cond(1, |
| 1212 ErrorCode::TP_32BIT, | 1259 ErrorCode::TP_32BIT, |
| 1213 ErrorCode::OP_EQUAL, | 1260 ErrorCode::OP_EQUAL, |
| 1214 0x55555555, | 1261 0x55555555, |
| 1215 ErrorCode(1), | 1262 ErrorCode(1), |
| 1216 ErrorCode(2)), | 1263 ErrorCode(2)), |
| 1217 // The BPF compiler and the BPF interpreter in the kernel are | 1264 // The BPF compiler and the BPF interpreter in the kernel are |
| 1218 // (mostly) agnostic of the host platform's word size. The compiler | 1265 // (mostly) agnostic of the host platform's word size. The compiler |
| 1219 // will happily generate code that tests a 64bit value, and the | 1266 // will happily generate code that tests a 64bit value, and the |
| 1220 // interpreter will happily perform this test. | 1267 // interpreter will happily perform this test. |
| 1221 // But unless there is a kernel bug, there is no way for us to pass | 1268 // But unless there is a kernel bug, there is no way for us to pass |
| 1222 // in a 64bit quantity on a 32bit platform. The upper 32bits should | 1269 // in a 64bit quantity on a 32bit platform. The upper 32bits should |
| 1223 // always be zero. So, this test should always evaluate as false on | 1270 // always be zero. So, this test should always evaluate as false on |
| 1224 // 32bit systems. | 1271 // 32bit systems. |
| 1225 sandbox->Cond(1, | 1272 sandbox->Cond(1, |
| 1226 ErrorCode::TP_64BIT, | 1273 ErrorCode::TP_64BIT, |
| 1227 ErrorCode::OP_EQUAL, | 1274 ErrorCode::OP_EQUAL, |
| 1228 0x55555555AAAAAAAAULL, | 1275 0x55555555AAAAAAAAULL, |
| 1229 ErrorCode(1), | 1276 ErrorCode(1), |
| 1230 ErrorCode(2))); | 1277 ErrorCode(2))); |
| 1231 } else { | |
| 1232 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 1233 } | 1278 } |
| 1279 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1234 } | 1280 } |
| 1235 | 1281 |
| 1236 BPF_TEST(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { | 1282 BPF_TEST_C(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { |
| 1237 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); | 1283 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); |
| 1238 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); | 1284 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); |
| 1239 #if __SIZEOF_POINTER__ > 4 | 1285 #if __SIZEOF_POINTER__ > 4 |
| 1240 // On 32bit machines, there is no way to pass a 64bit argument through the | 1286 // On 32bit machines, there is no way to pass a 64bit argument through the |
| 1241 // syscall interface. So, we have to skip the part of the test that requires | 1287 // syscall interface. So, we have to skip the part of the test that requires |
| 1242 // 64bit arguments. | 1288 // 64bit arguments. |
| 1243 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); | 1289 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); |
| 1244 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); | 1290 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); |
| 1245 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); | 1291 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); |
| 1246 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); | 1292 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); |
| 1247 #else | 1293 #else |
| 1248 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); | 1294 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); |
| 1249 #endif | 1295 #endif |
| 1250 } | 1296 } |
| 1251 | 1297 |
| 1252 #if __SIZEOF_POINTER__ > 4 | 1298 #if __SIZEOF_POINTER__ > 4 |
| 1253 // On 32bit machines, there is no way to pass a 64bit argument through the | 1299 // On 32bit machines, there is no way to pass a 64bit argument through the |
| 1254 // syscall interface. So, we have to skip the part of the test that requires | 1300 // syscall interface. So, we have to skip the part of the test that requires |
| 1255 // 64bit arguments. | 1301 // 64bit arguments. |
| 1256 BPF_DEATH_TEST(SandboxBPF, | 1302 BPF_DEATH_TEST_C(SandboxBPF, |
| 1257 EqualityArgumentUnallowed64bit, | 1303 EqualityArgumentUnallowed64bit, |
| 1258 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1304 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
| 1259 EqualityArgumentWidthPolicy) { | 1305 EqualityArgumentWidthPolicy) { |
| 1260 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); | 1306 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); |
| 1261 } | 1307 } |
| 1262 #endif | 1308 #endif |
| 1263 | 1309 |
| 1264 ErrorCode EqualityWithNegativeArgumentsPolicy(SandboxBPF* sandbox, | 1310 class EqualityWithNegativeArgumentsPolicy : public SandboxBPFPolicy { |
| 1265 int sysno, | 1311 public: |
| 1266 void*) { | 1312 EqualityWithNegativeArgumentsPolicy() {} |
| 1267 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1313 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 1268 // FIXME: we should really not have to do that in a trivial policy | 1314 int sysno) const OVERRIDE { |
| 1269 return ErrorCode(ENOSYS); | 1315 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 1270 } else if (sysno == __NR_uname) { | 1316 if (sysno == __NR_uname) { |
| 1271 return sandbox->Cond(0, | 1317 return sandbox->Cond(0, |
| 1272 ErrorCode::TP_32BIT, | 1318 ErrorCode::TP_32BIT, |
| 1273 ErrorCode::OP_EQUAL, | 1319 ErrorCode::OP_EQUAL, |
| 1274 0xFFFFFFFF, | 1320 0xFFFFFFFF, |
| 1275 ErrorCode(1), | 1321 ErrorCode(1), |
| 1276 ErrorCode(2)); | 1322 ErrorCode(2)); |
| 1277 } else { | 1323 } |
| 1278 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1324 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1279 } | 1325 } |
| 1280 } | |
| 1281 | 1326 |
| 1282 BPF_TEST(SandboxBPF, | 1327 private: |
| 1283 EqualityWithNegativeArguments, | 1328 DISALLOW_COPY_AND_ASSIGN(EqualityWithNegativeArgumentsPolicy); |
| 1284 EqualityWithNegativeArgumentsPolicy) { | 1329 }; |
| 1330 |
| 1331 BPF_TEST_C(SandboxBPF, |
| 1332 EqualityWithNegativeArguments, |
| 1333 EqualityWithNegativeArgumentsPolicy) { |
| 1285 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); | 1334 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); |
| 1286 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); | 1335 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); |
| 1287 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); | 1336 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); |
| 1288 } | 1337 } |
| 1289 | 1338 |
| 1290 #if __SIZEOF_POINTER__ > 4 | 1339 #if __SIZEOF_POINTER__ > 4 |
| 1291 BPF_DEATH_TEST(SandboxBPF, | 1340 BPF_DEATH_TEST_C(SandboxBPF, |
| 1292 EqualityWithNegative64bitArguments, | 1341 EqualityWithNegative64bitArguments, |
| 1293 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1342 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
| 1294 EqualityWithNegativeArgumentsPolicy) { | 1343 EqualityWithNegativeArgumentsPolicy) { |
| 1295 // When expecting a 32bit system call argument, we look at the MSB of the | 1344 // When expecting a 32bit system call argument, we look at the MSB of the |
| 1296 // 64bit value and allow both "0" and "-1". But the latter is allowed only | 1345 // 64bit value and allow both "0" and "-1". But the latter is allowed only |
| 1297 // iff the LSB was negative. So, this death test should error out. | 1346 // iff the LSB was negative. So, this death test should error out. |
| 1298 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); | 1347 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); |
| 1299 } | 1348 } |
| 1300 #endif | 1349 #endif |
| 1301 ErrorCode AllBitTestPolicy(SandboxBPF* sandbox, int sysno, void *) { | 1350 class AllBitTestPolicy : public SandboxBPFPolicy { |
| 1351 public: |
| 1352 AllBitTestPolicy() {} |
| 1353 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 1354 int sysno) const OVERRIDE; |
| 1355 |
| 1356 private: |
| 1357 DISALLOW_COPY_AND_ASSIGN(AllBitTestPolicy); |
| 1358 }; |
| 1359 |
| 1360 ErrorCode AllBitTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
| 1361 int sysno) const { |
| 1362 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 1302 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of | 1363 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of |
| 1303 // different bitmasks. We try to find bitmasks that could conceivably | 1364 // different bitmasks. We try to find bitmasks that could conceivably |
| 1304 // touch corner cases. | 1365 // touch corner cases. |
| 1305 // For all of these tests, we override the uname(). We can make use with | 1366 // For all of these tests, we override the uname(). We can make use with |
| 1306 // a single system call number, as we use the first system call argument to | 1367 // a single system call number, as we use the first system call argument to |
| 1307 // select the different bit masks that we want to test against. | 1368 // select the different bit masks that we want to test against. |
| 1308 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1369 if (sysno == __NR_uname) { |
| 1309 // FIXME: we should really not have to do that in a trivial policy | |
| 1310 return ErrorCode(ENOSYS); | |
| 1311 } else if (sysno == __NR_uname) { | |
| 1312 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1370 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
| 1313 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1371 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1314 0x0, | 1372 0x0, |
| 1315 ErrorCode(1), ErrorCode(0)), | 1373 ErrorCode(1), ErrorCode(0)), |
| 1316 | 1374 |
| 1317 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, | 1375 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, |
| 1318 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1376 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1319 0x1, | 1377 0x1, |
| 1320 ErrorCode(1), ErrorCode(0)), | 1378 ErrorCode(1), ErrorCode(0)), |
| 1321 | 1379 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | 1415 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1358 0x300000000ULL, | 1416 0x300000000ULL, |
| 1359 ErrorCode(1), ErrorCode(0)), | 1417 ErrorCode(1), ErrorCode(0)), |
| 1360 | 1418 |
| 1361 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, | 1419 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, |
| 1362 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | 1420 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
| 1363 0x100000001ULL, | 1421 0x100000001ULL, |
| 1364 ErrorCode(1), ErrorCode(0)), | 1422 ErrorCode(1), ErrorCode(0)), |
| 1365 | 1423 |
| 1366 sandbox->Kill("Invalid test case number")))))))))))); | 1424 sandbox->Kill("Invalid test case number")))))))))))); |
| 1367 } else { | |
| 1368 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 1369 } | 1425 } |
| 1426 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1370 } | 1427 } |
| 1371 | 1428 |
| 1372 // Define a macro that performs tests using our test policy. | 1429 // Define a macro that performs tests using our test policy. |
| 1373 // NOTE: Not all of the arguments in this macro are actually used! | 1430 // NOTE: Not all of the arguments in this macro are actually used! |
| 1374 // They are here just to serve as documentation of the conditions | 1431 // They are here just to serve as documentation of the conditions |
| 1375 // implemented in the test policy. | 1432 // implemented in the test policy. |
| 1376 // Most notably, "op" and "mask" are unused by the macro. If you want | 1433 // Most notably, "op" and "mask" are unused by the macro. If you want |
| 1377 // to make changes to these values, you will have to edit the | 1434 // to make changes to these values, you will have to edit the |
| 1378 // test policy instead. | 1435 // test policy instead. |
| 1379 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ | 1436 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ |
| 1380 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) | 1437 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) |
| 1381 | 1438 |
| 1382 // Our uname() system call returns ErrorCode(1) for success and | 1439 // Our uname() system call returns ErrorCode(1) for success and |
| 1383 // ErrorCode(0) for failure. SandboxSyscall() turns this into an | 1440 // ErrorCode(0) for failure. SandboxSyscall() turns this into an |
| 1384 // exit code of -1 or 0. | 1441 // exit code of -1 or 0. |
| 1385 #define EXPECT_FAILURE 0 | 1442 #define EXPECT_FAILURE 0 |
| 1386 #define EXPECT_SUCCESS -1 | 1443 #define EXPECT_SUCCESS -1 |
| 1387 | 1444 |
| 1388 // A couple of our tests behave differently on 32bit and 64bit systems, as | 1445 // A couple of our tests behave differently on 32bit and 64bit systems, as |
| 1389 // there is no way for a 32bit system call to pass in a 64bit system call | 1446 // there is no way for a 32bit system call to pass in a 64bit system call |
| 1390 // argument "arg". | 1447 // argument "arg". |
| 1391 // We expect these tests to succeed on 64bit systems, but to tail on 32bit | 1448 // We expect these tests to succeed on 64bit systems, but to tail on 32bit |
| 1392 // systems. | 1449 // systems. |
| 1393 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) | 1450 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) |
| 1394 BPF_TEST(SandboxBPF, AllBitTests, AllBitTestPolicy) { | 1451 BPF_TEST_C(SandboxBPF, AllBitTests, AllBitTestPolicy) { |
| 1395 // 32bit test: all of 0x0 (should always be true) | 1452 // 32bit test: all of 0x0 (should always be true) |
| 1396 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); | 1453 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1397 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); | 1454 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1398 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); | 1455 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1399 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); | 1456 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1400 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); | 1457 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); |
| 1401 | 1458 |
| 1402 // 32bit test: all of 0x1 | 1459 // 32bit test: all of 0x1 |
| 1403 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); | 1460 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); |
| 1404 BITMASK_TEST( 1, 1, ALLBITS32, 0x1, EXPECT_SUCCESS); | 1461 BITMASK_TEST( 1, 1, ALLBITS32, 0x1, EXPECT_SUCCESS); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1487 | 1544 |
| 1488 // 64bit test: all of 0x100000001 | 1545 // 64bit test: all of 0x100000001 |
| 1489 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1546 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1490 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1547 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1491 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1548 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1492 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1549 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
| 1493 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1550 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); |
| 1494 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1551 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
| 1495 } | 1552 } |
| 1496 | 1553 |
| 1497 ErrorCode AnyBitTestPolicy(SandboxBPF* sandbox, int sysno, void*) { | 1554 class AnyBitTestPolicy : public SandboxBPFPolicy { |
| 1555 public: |
| 1556 AnyBitTestPolicy() {} |
| 1557 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 1558 int sysno) const OVERRIDE; |
| 1559 |
| 1560 private: |
| 1561 DISALLOW_COPY_AND_ASSIGN(AnyBitTestPolicy); |
| 1562 }; |
| 1563 |
| 1564 ErrorCode AnyBitTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, |
| 1565 int sysno) const { |
| 1566 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 1498 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of | 1567 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of |
| 1499 // different bitmasks. We try to find bitmasks that could conceivably | 1568 // different bitmasks. We try to find bitmasks that could conceivably |
| 1500 // touch corner cases. | 1569 // touch corner cases. |
| 1501 // For all of these tests, we override the uname(). We can make use with | 1570 // For all of these tests, we override the uname(). We can make use with |
| 1502 // a single system call number, as we use the first system call argument to | 1571 // a single system call number, as we use the first system call argument to |
| 1503 // select the different bit masks that we want to test against. | 1572 // select the different bit masks that we want to test against. |
| 1504 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1573 if (sysno == __NR_uname) { |
| 1505 // FIXME: we should really not have to do that in a trivial policy | |
| 1506 return ErrorCode(ENOSYS); | |
| 1507 } else if (sysno == __NR_uname) { | |
| 1508 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1574 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
| 1509 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1575 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1510 0x0, | 1576 0x0, |
| 1511 ErrorCode(1), ErrorCode(0)), | 1577 ErrorCode(1), ErrorCode(0)), |
| 1512 | 1578 |
| 1513 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, | 1579 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, |
| 1514 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1580 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1515 0x1, | 1581 0x1, |
| 1516 ErrorCode(1), ErrorCode(0)), | 1582 ErrorCode(1), ErrorCode(0)), |
| 1517 | 1583 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1622 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1557 0x300000000ULL, | 1623 0x300000000ULL, |
| 1558 ErrorCode(1), ErrorCode(0)), | 1624 ErrorCode(1), ErrorCode(0)), |
| 1559 | 1625 |
| 1560 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, | 1626 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, |
| 1561 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1627 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1562 0x100000001ULL, | 1628 0x100000001ULL, |
| 1563 ErrorCode(1), ErrorCode(0)), | 1629 ErrorCode(1), ErrorCode(0)), |
| 1564 | 1630 |
| 1565 sandbox->Kill("Invalid test case number")))))))))))); | 1631 sandbox->Kill("Invalid test case number")))))))))))); |
| 1566 } else { | |
| 1567 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 1568 } | 1632 } |
| 1633 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1569 } | 1634 } |
| 1570 | 1635 |
| 1571 BPF_TEST(SandboxBPF, AnyBitTests, AnyBitTestPolicy) { | 1636 BPF_TEST_C(SandboxBPF, AnyBitTests, AnyBitTestPolicy) { |
| 1572 // 32bit test: any of 0x0 (should always be false) | 1637 // 32bit test: any of 0x0 (should always be false) |
| 1573 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); | 1638 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); |
| 1574 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); | 1639 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); |
| 1575 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); | 1640 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); |
| 1576 BITMASK_TEST( 0, 0xFFFFFFFFU, ANYBITS32, 0x0, EXPECT_FAILURE); | 1641 BITMASK_TEST( 0, 0xFFFFFFFFU, ANYBITS32, 0x0, EXPECT_FAILURE); |
| 1577 BITMASK_TEST( 0, -1LL, ANYBITS32, 0x0, EXPECT_FAILURE); | 1642 BITMASK_TEST( 0, -1LL, ANYBITS32, 0x0, EXPECT_FAILURE); |
| 1578 | 1643 |
| 1579 // 32bit test: any of 0x1 | 1644 // 32bit test: any of 0x1 |
| 1580 BITMASK_TEST( 1, 0, ANYBITS32, 0x1, EXPECT_FAILURE); | 1645 BITMASK_TEST( 1, 0, ANYBITS32, 0x1, EXPECT_FAILURE); |
| 1581 BITMASK_TEST( 1, 1, ANYBITS32, 0x1, EXPECT_SUCCESS); | 1646 BITMASK_TEST( 1, 1, ANYBITS32, 0x1, EXPECT_SUCCESS); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1691 (long long)args.args[0], | 1756 (long long)args.args[0], |
| 1692 (long long)args.args[1], | 1757 (long long)args.args[1], |
| 1693 (long long)args.args[2], | 1758 (long long)args.args[2], |
| 1694 (long long)args.args[3], | 1759 (long long)args.args[3], |
| 1695 (long long)args.args[4], | 1760 (long long)args.args[4], |
| 1696 (long long)args.args[5], | 1761 (long long)args.args[5], |
| 1697 msg); | 1762 msg); |
| 1698 } | 1763 } |
| 1699 return -EPERM; | 1764 return -EPERM; |
| 1700 } | 1765 } |
| 1701 ErrorCode PthreadPolicyEquality(SandboxBPF* sandbox, int sysno, void* aux) { | 1766 |
| 1767 class PthreadPolicyEquality : public SandboxBPFPolicy { |
| 1768 public: |
| 1769 PthreadPolicyEquality() {} |
| 1770 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 1771 int sysno) const OVERRIDE; |
| 1772 |
| 1773 private: |
| 1774 DISALLOW_COPY_AND_ASSIGN(PthreadPolicyEquality); |
| 1775 }; |
| 1776 |
| 1777 ErrorCode PthreadPolicyEquality::EvaluateSyscall(SandboxBPF* sandbox, |
| 1778 int sysno) const { |
| 1779 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 1702 // This policy allows creating threads with pthread_create(). But it | 1780 // This policy allows creating threads with pthread_create(). But it |
| 1703 // doesn't allow any other uses of clone(). Most notably, it does not | 1781 // doesn't allow any other uses of clone(). Most notably, it does not |
| 1704 // allow callers to implement fork() or vfork() by passing suitable flags | 1782 // allow callers to implement fork() or vfork() by passing suitable flags |
| 1705 // to the clone() system call. | 1783 // to the clone() system call. |
| 1706 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1784 if (sysno == __NR_clone) { |
| 1707 // FIXME: we should really not have to do that in a trivial policy | |
| 1708 return ErrorCode(ENOSYS); | |
| 1709 } else if (sysno == __NR_clone) { | |
| 1710 // We have seen two different valid combinations of flags. Glibc | 1785 // We have seen two different valid combinations of flags. Glibc |
| 1711 // uses the more modern flags, sets the TLS from the call to clone(), and | 1786 // uses the more modern flags, sets the TLS from the call to clone(), and |
| 1712 // uses futexes to monitor threads. Android's C run-time library, doesn't | 1787 // uses futexes to monitor threads. Android's C run-time library, doesn't |
| 1713 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. | 1788 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
| 1714 // More recent versions of Android don't set CLONE_DETACHED anymore, so | 1789 // More recent versions of Android don't set CLONE_DETACHED anymore, so |
| 1715 // the last case accounts for that. | 1790 // the last case accounts for that. |
| 1716 // The following policy is very strict. It only allows the exact masks | 1791 // The following policy is very strict. It only allows the exact masks |
| 1717 // that we have seen in known implementations. It is probably somewhat | 1792 // that we have seen in known implementations. It is probably somewhat |
| 1718 // stricter than what we would want to do. | 1793 // stricter than what we would want to do. |
| 1719 const uint64_t kGlibcCloneMask = | 1794 const uint64_t kGlibcCloneMask = |
| 1720 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | | 1795 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | |
| 1721 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | | 1796 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | |
| 1722 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; | 1797 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; |
| 1723 const uint64_t kBaseAndroidCloneMask = | 1798 const uint64_t kBaseAndroidCloneMask = |
| 1724 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | | 1799 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | |
| 1725 CLONE_THREAD | CLONE_SYSVSEM; | 1800 CLONE_THREAD | CLONE_SYSVSEM; |
| 1726 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1801 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 1727 kGlibcCloneMask, | 1802 kGlibcCloneMask, |
| 1728 ErrorCode(ErrorCode::ERR_ALLOWED), | 1803 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1729 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1804 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 1730 kBaseAndroidCloneMask | CLONE_DETACHED, | 1805 kBaseAndroidCloneMask | CLONE_DETACHED, |
| 1731 ErrorCode(ErrorCode::ERR_ALLOWED), | 1806 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1732 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1807 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 1733 kBaseAndroidCloneMask, | 1808 kBaseAndroidCloneMask, |
| 1734 ErrorCode(ErrorCode::ERR_ALLOWED), | 1809 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1735 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); | 1810 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); |
| 1736 } else { | |
| 1737 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 1738 } | 1811 } |
| 1812 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1739 } | 1813 } |
| 1740 | 1814 |
| 1741 ErrorCode PthreadPolicyBitMask(SandboxBPF* sandbox, int sysno, void* aux) { | 1815 class PthreadPolicyBitMask : public SandboxBPFPolicy { |
| 1816 public: |
| 1817 PthreadPolicyBitMask() {} |
| 1818 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
| 1819 int sysno) const OVERRIDE; |
| 1820 |
| 1821 private: |
| 1822 DISALLOW_COPY_AND_ASSIGN(PthreadPolicyBitMask); |
| 1823 }; |
| 1824 |
| 1825 ErrorCode PthreadPolicyBitMask::EvaluateSyscall(SandboxBPF* sandbox, |
| 1826 int sysno) const { |
| 1827 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 1742 // This policy allows creating threads with pthread_create(). But it | 1828 // This policy allows creating threads with pthread_create(). But it |
| 1743 // doesn't allow any other uses of clone(). Most notably, it does not | 1829 // doesn't allow any other uses of clone(). Most notably, it does not |
| 1744 // allow callers to implement fork() or vfork() by passing suitable flags | 1830 // allow callers to implement fork() or vfork() by passing suitable flags |
| 1745 // to the clone() system call. | 1831 // to the clone() system call. |
| 1746 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1832 if (sysno == __NR_clone) { |
| 1747 // FIXME: we should really not have to do that in a trivial policy | |
| 1748 return ErrorCode(ENOSYS); | |
| 1749 } else if (sysno == __NR_clone) { | |
| 1750 // We have seen two different valid combinations of flags. Glibc | 1833 // We have seen two different valid combinations of flags. Glibc |
| 1751 // uses the more modern flags, sets the TLS from the call to clone(), and | 1834 // uses the more modern flags, sets the TLS from the call to clone(), and |
| 1752 // uses futexes to monitor threads. Android's C run-time library, doesn't | 1835 // uses futexes to monitor threads. Android's C run-time library, doesn't |
| 1753 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. | 1836 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
| 1754 // The following policy allows for either combination of flags, but it | 1837 // The following policy allows for either combination of flags, but it |
| 1755 // is generally a little more conservative than strictly necessary. We | 1838 // is generally a little more conservative than strictly necessary. We |
| 1756 // err on the side of rather safe than sorry. | 1839 // err on the side of rather safe than sorry. |
| 1757 // Very noticeably though, we disallow fork() (which is often just a | 1840 // Very noticeably though, we disallow fork() (which is often just a |
| 1758 // wrapper around clone()). | 1841 // wrapper around clone()). |
| 1759 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1842 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1771 ErrorCode(ErrorCode::ERR_ALLOWED), | 1854 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 1772 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1855 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
| 1773 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, | 1856 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, |
| 1774 sandbox->Trap(PthreadTrapHandler, | 1857 sandbox->Trap(PthreadTrapHandler, |
| 1775 "Must set either all or none of the TLS" | 1858 "Must set either all or none of the TLS" |
| 1776 " and futex bits in call to clone()"), | 1859 " and futex bits in call to clone()"), |
| 1777 ErrorCode(ErrorCode::ERR_ALLOWED))), | 1860 ErrorCode(ErrorCode::ERR_ALLOWED))), |
| 1778 sandbox->Trap(PthreadTrapHandler, | 1861 sandbox->Trap(PthreadTrapHandler, |
| 1779 "Missing mandatory CLONE_XXX flags " | 1862 "Missing mandatory CLONE_XXX flags " |
| 1780 "when creating new thread"))); | 1863 "when creating new thread"))); |
| 1781 } else { | |
| 1782 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 1783 } | 1864 } |
| 1865 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 1784 } | 1866 } |
| 1785 | 1867 |
| 1786 static void* ThreadFnc(void* arg) { | 1868 static void* ThreadFnc(void* arg) { |
| 1787 ++*reinterpret_cast<int*>(arg); | 1869 ++*reinterpret_cast<int*>(arg); |
| 1788 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); | 1870 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); |
| 1789 return NULL; | 1871 return NULL; |
| 1790 } | 1872 } |
| 1791 | 1873 |
| 1792 static void PthreadTest() { | 1874 static void PthreadTest() { |
| 1793 // Attempt to start a joinable thread. This should succeed. | 1875 // Attempt to start a joinable thread. This should succeed. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1815 // run-time libraries other than glibc might call __NR_fork instead of | 1897 // run-time libraries other than glibc might call __NR_fork instead of |
| 1816 // __NR_clone, and that would introduce a bogus test failure. | 1898 // __NR_clone, and that would introduce a bogus test failure. |
| 1817 int pid; | 1899 int pid; |
| 1818 BPF_ASSERT(SandboxSyscall(__NR_clone, | 1900 BPF_ASSERT(SandboxSyscall(__NR_clone, |
| 1819 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, | 1901 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, |
| 1820 0, | 1902 0, |
| 1821 0, | 1903 0, |
| 1822 &pid) == -EPERM); | 1904 &pid) == -EPERM); |
| 1823 } | 1905 } |
| 1824 | 1906 |
| 1825 BPF_TEST(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); } | 1907 BPF_TEST_C(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { |
| 1908 PthreadTest(); |
| 1909 } |
| 1826 | 1910 |
| 1827 BPF_TEST(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); } | 1911 BPF_TEST_C(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { |
| 1912 PthreadTest(); |
| 1913 } |
| 1828 | 1914 |
| 1829 } // namespace | 1915 } // namespace |
| 1830 | 1916 |
| 1831 } // namespace sandbox | 1917 } // namespace sandbox |
| OLD | NEW |