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 |