| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 // Sanitizers internally use some syscalls which non-SFI NaCl disallows. | 5 // Sanitizers internally use some syscalls which non-SFI NaCl disallows. |
| 6 #if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \ | 6 #if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \ |
| 7 !defined(MEMORY_SANITIZER) && !defined(LEAK_SANITIZER) | 7 !defined(MEMORY_SANITIZER) && !defined(LEAK_SANITIZER) |
| 8 | 8 |
| 9 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" | 9 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" |
| 10 | 10 |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { | 424 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
| 425 char* next_brk = static_cast<char*>(sbrk(0)) + getpagesize(); | 425 char* next_brk = static_cast<char*>(sbrk(0)) + getpagesize(); |
| 426 // The kernel interface must return zero for brk. | 426 // The kernel interface must return zero for brk. |
| 427 BPF_ASSERT_EQ(0, syscall(__NR_brk, next_brk)); | 427 BPF_ASSERT_EQ(0, syscall(__NR_brk, next_brk)); |
| 428 // The libc wrapper translates it to ENOMEM. | 428 // The libc wrapper translates it to ENOMEM. |
| 429 errno = 0; | 429 errno = 0; |
| 430 BPF_ASSERT_EQ(-1, brk(next_brk)); | 430 BPF_ASSERT_EQ(-1, brk(next_brk)); |
| 431 BPF_ASSERT_EQ(ENOMEM, errno); | 431 BPF_ASSERT_EQ(ENOMEM, errno); |
| 432 } | 432 } |
| 433 | 433 |
| 434 // clockid restrictions are mostly tested in sandbox/ with the |
| 435 // RestrictClockID() unittests. Some basic tests are duplicated here as |
| 436 // a precaution. |
| 437 |
| 434 void CheckClock(clockid_t clockid) { | 438 void CheckClock(clockid_t clockid) { |
| 435 struct timespec ts; | 439 struct timespec ts; |
| 436 ts.tv_sec = ts.tv_nsec = -1; | 440 ts.tv_sec = ts.tv_nsec = -1; |
| 437 BPF_ASSERT_EQ(0, clock_gettime(clockid, &ts)); | 441 BPF_ASSERT_EQ(0, clock_gettime(clockid, &ts)); |
| 438 BPF_ASSERT_LE(0, ts.tv_sec); | 442 BPF_ASSERT_LE(0, ts.tv_sec); |
| 439 BPF_ASSERT_LE(0, ts.tv_nsec); | 443 BPF_ASSERT_LE(0, ts.tv_nsec); |
| 440 } | 444 } |
| 441 | 445 |
| 442 BPF_TEST_C(NaClNonSfiSandboxTest, | 446 BPF_TEST_C(NaClNonSfiSandboxTest, |
| 443 clock_gettime_allowed, | 447 clock_gettime_allowed, |
| 444 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { | 448 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
| 445 CheckClock(CLOCK_MONOTONIC); | 449 CheckClock(CLOCK_MONOTONIC); |
| 446 CheckClock(CLOCK_PROCESS_CPUTIME_ID); | 450 CheckClock(CLOCK_PROCESS_CPUTIME_ID); |
| 447 CheckClock(CLOCK_REALTIME); | 451 CheckClock(CLOCK_REALTIME); |
| 448 CheckClock(CLOCK_THREAD_CPUTIME_ID); | 452 CheckClock(CLOCK_THREAD_CPUTIME_ID); |
| 449 } | 453 } |
| 450 | 454 |
| 451 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, | 455 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
| 452 clock_gettime_crash_monotonic_raw, | 456 clock_gettime_crash_monotonic_raw, |
| 453 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), | 457 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
| 454 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { | 458 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
| 455 struct timespec ts; | 459 struct timespec ts; |
| 456 clock_gettime(CLOCK_MONOTONIC_RAW, &ts); | 460 clock_gettime(CLOCK_MONOTONIC_RAW, &ts); |
| 457 } | 461 } |
| 458 | 462 |
| 459 #if defined(OS_CHROMEOS) | |
| 460 | |
| 461 // A custom BPF tester delegate to run IsRunningOnChromeOS() before | |
| 462 // the sandbox is enabled because we cannot run it with non-SFI BPF | |
| 463 // sandbox enabled. | |
| 464 class ClockSystemTesterDelegate : public sandbox::BPFTesterDelegate { | |
| 465 public: | |
| 466 ClockSystemTesterDelegate() | |
| 467 : is_running_on_chromeos_(base::SysInfo::IsRunningOnChromeOS()) {} | |
| 468 virtual ~ClockSystemTesterDelegate() {} | |
| 469 | |
| 470 virtual scoped_ptr<sandbox::SandboxBPFPolicy> GetSandboxBPFPolicy() OVERRIDE { | |
| 471 return scoped_ptr<sandbox::SandboxBPFPolicy>( | |
| 472 new nacl::nonsfi::NaClNonSfiBPFSandboxPolicy()); | |
| 473 } | |
| 474 virtual void RunTestFunction() OVERRIDE { | |
| 475 if (is_running_on_chromeos_) { | |
| 476 CheckClock(base::TimeTicks::kClockSystemTrace); | |
| 477 } else { | |
| 478 struct timespec ts; | |
| 479 // kClockSystemTrace is 11, which is CLOCK_THREAD_CPUTIME_ID of | |
| 480 // the init process (pid=1). If kernel supports this feature, | |
| 481 // this may succeed even if this is not running on Chrome OS. We | |
| 482 // just check this clock_gettime call does not crash. | |
| 483 clock_gettime(base::TimeTicks::kClockSystemTrace, &ts); | |
| 484 } | |
| 485 } | |
| 486 | |
| 487 private: | |
| 488 const bool is_running_on_chromeos_; | |
| 489 DISALLOW_COPY_AND_ASSIGN(ClockSystemTesterDelegate); | |
| 490 }; | |
| 491 | |
| 492 BPF_TEST_D(BPFTest, BPFTestWithDelegateClass, ClockSystemTesterDelegate); | |
| 493 | |
| 494 #else | |
| 495 | |
| 496 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, | |
| 497 clock_gettime_crash_system_trace, | |
| 498 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), | |
| 499 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { | |
| 500 struct timespec ts; | |
| 501 clock_gettime(base::TimeTicks::kClockSystemTrace, &ts); | |
| 502 } | |
| 503 | |
| 504 #endif // defined(OS_CHROMEOS) | |
| 505 | |
| 506 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, | |
| 507 clock_gettime_crash_cpu_clock, | |
| 508 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), | |
| 509 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { | |
| 510 // We can't use clock_getcpuclockid() because it's not implemented in newlib, | |
| 511 // and it might not work inside the sandbox anyway. | |
| 512 const pid_t kInitPID = 1; | |
| 513 const clockid_t kInitCPUClockID = | |
| 514 MAKE_PROCESS_CPUCLOCK(kInitPID, CPUCLOCK_SCHED); | |
| 515 | |
| 516 struct timespec ts; | |
| 517 clock_gettime(kInitCPUClockID, &ts); | |
| 518 } | |
| 519 | |
| 520 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, | 463 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, |
| 521 invalid_syscall_crash, | 464 invalid_syscall_crash, |
| 522 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), | 465 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
| 523 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { | 466 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { |
| 524 sandbox::Syscall::InvalidCall(); | 467 sandbox::Syscall::InvalidCall(); |
| 525 } | 468 } |
| 526 | 469 |
| 527 // The following test cases check if syscalls return EPERM regardless | 470 // The following test cases check if syscalls return EPERM regardless |
| 528 // of arguments. | 471 // of arguments. |
| 529 #define RESTRICT_SYSCALL_EPERM_TEST(name) \ | 472 #define RESTRICT_SYSCALL_EPERM_TEST(name) \ |
| (...skipping 22 matching lines...) Expand all Loading... |
| 552 RESTRICT_SYSCALL_EPERM_TEST(ptrace); | 495 RESTRICT_SYSCALL_EPERM_TEST(ptrace); |
| 553 RESTRICT_SYSCALL_EPERM_TEST(set_robust_list); | 496 RESTRICT_SYSCALL_EPERM_TEST(set_robust_list); |
| 554 #if defined(__i386__) || defined(__x86_64__) | 497 #if defined(__i386__) || defined(__x86_64__) |
| 555 RESTRICT_SYSCALL_EPERM_TEST(time); | 498 RESTRICT_SYSCALL_EPERM_TEST(time); |
| 556 #endif | 499 #endif |
| 557 | 500 |
| 558 } // namespace | 501 } // namespace |
| 559 | 502 |
| 560 #endif // !ADDRESS_SANITIZER && !THREAD_SANITIZER && | 503 #endif // !ADDRESS_SANITIZER && !THREAD_SANITIZER && |
| 561 // !MEMORY_SANITIZER && !LEAK_SANITIZER | 504 // !MEMORY_SANITIZER && !LEAK_SANITIZER |
| OLD | NEW |