| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <fcntl.h> | 6 #include <fcntl.h> |
| 7 #include <pthread.h> | 7 #include <pthread.h> |
| 8 #include <sched.h> | 8 #include <sched.h> |
| 9 #include <signal.h> | 9 #include <signal.h> |
| 10 #include <sys/prctl.h> | 10 #include <sys/prctl.h> |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 setenv(kSandboxDebuggingEnv, "t", 0); | 644 setenv(kSandboxDebuggingEnv, "t", 0); |
| 645 Die::SuppressInfoMessages(true); | 645 Die::SuppressInfoMessages(true); |
| 646 | 646 |
| 647 // Some system calls must always be allowed, if our policy wants to make | 647 // Some system calls must always be allowed, if our policy wants to make |
| 648 // use of UnsafeTrap() | 648 // use of UnsafeTrap() |
| 649 if (SandboxBPF::IsRequiredForUnsafeTrap(sysno)) | 649 if (SandboxBPF::IsRequiredForUnsafeTrap(sysno)) |
| 650 return Allow(); | 650 return Allow(); |
| 651 return UnsafeTrap(AllowRedirectedSyscall, NULL); | 651 return UnsafeTrap(AllowRedirectedSyscall, NULL); |
| 652 } | 652 } |
| 653 | 653 |
| 654 #if !defined(ADDRESS_SANITIZER) | |
| 655 // ASan does not allow changing the signal handler for SIGBUS, and treats it as | |
| 656 // a fatal signal. | |
| 657 | |
| 658 int bus_handler_fd_ = -1; | 654 int bus_handler_fd_ = -1; |
| 659 | 655 |
| 660 void SigBusHandler(int, siginfo_t* info, void* void_context) { | 656 void SigBusHandler(int, siginfo_t* info, void* void_context) { |
| 661 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); | 657 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); |
| 662 } | 658 } |
| 663 | 659 |
| 664 BPF_TEST_C(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) { | 660 BPF_TEST_C(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) { |
| 665 // We use the SIGBUS bit in the signal mask as a thread-local boolean | 661 // We use the SIGBUS bit in the signal mask as a thread-local boolean |
| 666 // value in the implementation of UnsafeTrap(). This is obviously a bit | 662 // value in the implementation of UnsafeTrap(). This is obviously a bit |
| 667 // of a hack that could conceivably interfere with code that uses SIGBUS | 663 // of a hack that could conceivably interfere with code that uses SIGBUS |
| 668 // in more traditional ways. This test verifies that basic functionality | 664 // in more traditional ways. This test verifies that basic functionality |
| 669 // of SIGBUS is not impacted, but it is certainly possibly to construe | 665 // of SIGBUS is not impacted, but it is certainly possibly to construe |
| 670 // more complex uses of signals where our use of the SIGBUS mask is not | 666 // more complex uses of signals where our use of the SIGBUS mask is not |
| 671 // 100% transparent. This is expected behavior. | 667 // 100% transparent. This is expected behavior. |
| 672 int fds[2]; | 668 int fds[2]; |
| 673 BPF_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); | 669 BPF_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); |
| 674 bus_handler_fd_ = fds[1]; | 670 bus_handler_fd_ = fds[1]; |
| 675 struct sigaction sa = {}; | 671 struct sigaction sa = {}; |
| 676 sa.sa_sigaction = SigBusHandler; | 672 sa.sa_sigaction = SigBusHandler; |
| 677 sa.sa_flags = SA_SIGINFO; | 673 sa.sa_flags = SA_SIGINFO; |
| 678 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); | 674 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); |
| 679 raise(SIGBUS); | 675 raise(SIGBUS); |
| 680 char c = '\000'; | 676 char c = '\000'; |
| 681 BPF_ASSERT(read(fds[0], &c, 1) == 1); | 677 BPF_ASSERT(read(fds[0], &c, 1) == 1); |
| 682 BPF_ASSERT(close(fds[0]) == 0); | 678 BPF_ASSERT(close(fds[0]) == 0); |
| 683 BPF_ASSERT(close(fds[1]) == 0); | 679 BPF_ASSERT(close(fds[1]) == 0); |
| 684 BPF_ASSERT(c == 0x55); | 680 BPF_ASSERT(c == 0x55); |
| 685 } | 681 } |
| 686 #endif // !defined(ADDRESS_SANITIZER) | |
| 687 | 682 |
| 688 BPF_TEST_C(SandboxBPF, SigMask, RedirectAllSyscallsPolicy) { | 683 BPF_TEST_C(SandboxBPF, SigMask, RedirectAllSyscallsPolicy) { |
| 689 // Signal masks are potentially tricky to handle. For instance, if we | 684 // Signal masks are potentially tricky to handle. For instance, if we |
| 690 // ever tried to update them from inside a Trap() or UnsafeTrap() handler, | 685 // ever tried to update them from inside a Trap() or UnsafeTrap() handler, |
| 691 // the call to sigreturn() at the end of the signal handler would undo | 686 // the call to sigreturn() at the end of the signal handler would undo |
| 692 // all of our efforts. So, it makes sense to test that sigprocmask() | 687 // all of our efforts. So, it makes sense to test that sigprocmask() |
| 693 // works, even if we have a policy in place that makes use of UnsafeTrap(). | 688 // works, even if we have a policy in place that makes use of UnsafeTrap(). |
| 694 // In practice, this works because we force sigprocmask() to be handled | 689 // In practice, this works because we force sigprocmask() to be handled |
| 695 // entirely in the kernel. | 690 // entirely in the kernel. |
| 696 sigset_t mask0, mask1, mask2; | 691 sigset_t mask0, mask1, mask2; |
| (...skipping 1553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2250 BPF_ASSERT_EQ(ENOSYS, errno); | 2245 BPF_ASSERT_EQ(ENOSYS, errno); |
| 2251 | 2246 |
| 2252 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); | 2247 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); |
| 2253 BPF_ASSERT_EQ(EPERM, errno); | 2248 BPF_ASSERT_EQ(EPERM, errno); |
| 2254 } | 2249 } |
| 2255 | 2250 |
| 2256 } // namespace | 2251 } // namespace |
| 2257 | 2252 |
| 2258 } // namespace bpf_dsl | 2253 } // namespace bpf_dsl |
| 2259 } // namespace sandbox | 2254 } // namespace sandbox |
| OLD | NEW |