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 "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 5 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
6 | 6 |
7 // Some headers on Android are missing cdefs: crbug.com/172337. | 7 // Some headers on Android are missing cdefs: crbug.com/172337. |
8 // (We can't use OS_ANDROID here since build_config.h is not included). | 8 // (We can't use OS_ANDROID here since build_config.h is not included). |
9 #if defined(ANDROID) | 9 #if defined(ANDROID) |
10 #include <sys/cdefs.h> | 10 #include <sys/cdefs.h> |
11 #endif | 11 #endif |
12 | 12 |
13 #include <errno.h> | 13 #include <errno.h> |
14 #include <fcntl.h> | 14 #include <fcntl.h> |
| 15 #include <signal.h> |
15 #include <string.h> | 16 #include <string.h> |
16 #include <sys/prctl.h> | 17 #include <sys/prctl.h> |
17 #include <sys/stat.h> | 18 #include <sys/stat.h> |
18 #include <sys/syscall.h> | 19 #include <sys/syscall.h> |
19 #include <sys/types.h> | 20 #include <sys/types.h> |
| 21 #include <sys/wait.h> |
20 #include <time.h> | 22 #include <time.h> |
21 #include <unistd.h> | 23 #include <unistd.h> |
22 | 24 |
23 #include <limits> | 25 #include <limits> |
24 | 26 |
25 #include "base/compiler_specific.h" | 27 #include "base/compiler_specific.h" |
26 #include "base/logging.h" | 28 #include "base/logging.h" |
27 #include "base/macros.h" | 29 #include "base/macros.h" |
28 #include "base/memory/scoped_ptr.h" | 30 #include "base/memory/scoped_ptr.h" |
29 #include "base/posix/eintr_wrapper.h" | 31 #include "base/posix/eintr_wrapper.h" |
30 #include "sandbox/linux/seccomp-bpf/codegen.h" | 32 #include "sandbox/linux/seccomp-bpf/codegen.h" |
| 33 #include "sandbox/linux/seccomp-bpf/errorcode.h" |
31 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" | 34 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" |
32 #include "sandbox/linux/seccomp-bpf/syscall.h" | 35 #include "sandbox/linux/seccomp-bpf/syscall.h" |
33 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" | 36 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" |
| 37 #include "sandbox/linux/seccomp-bpf/trap.h" |
34 #include "sandbox/linux/seccomp-bpf/verifier.h" | 38 #include "sandbox/linux/seccomp-bpf/verifier.h" |
35 #include "sandbox/linux/services/linux_syscalls.h" | 39 #include "sandbox/linux/services/linux_syscalls.h" |
36 | 40 |
37 namespace sandbox { | 41 namespace sandbox { |
38 | 42 |
39 namespace { | 43 namespace { |
40 | 44 |
41 const int kExpectedExitCode = 100; | 45 const int kExpectedExitCode = 100; |
42 | 46 |
| 47 #if defined(__i386__) || defined(__x86_64__) |
| 48 const bool kIsIntel = true; |
| 49 #else |
| 50 const bool kIsIntel = false; |
| 51 #endif |
| 52 #if defined(__x86_64__) && defined(__ILP32__) |
| 53 const bool kIsX32 = true; |
| 54 #else |
| 55 const bool kIsX32 = false; |
| 56 #endif |
| 57 |
| 58 const int kSyscallsRequiredForUnsafeTraps[] = { |
| 59 __NR_rt_sigprocmask, |
| 60 __NR_rt_sigreturn, |
| 61 #if defined(__NR_sigprocmask) |
| 62 __NR_sigprocmask, |
| 63 #endif |
| 64 #if defined(__NR_sigreturn) |
| 65 __NR_sigreturn, |
| 66 #endif |
| 67 }; |
| 68 |
43 bool HasExactlyOneBit(uint64_t x) { | 69 bool HasExactlyOneBit(uint64_t x) { |
44 // Common trick; e.g., see http://stackoverflow.com/a/108329. | 70 // Common trick; e.g., see http://stackoverflow.com/a/108329. |
45 return x != 0 && (x & (x - 1)) == 0; | 71 return x != 0 && (x & (x - 1)) == 0; |
46 } | 72 } |
47 | 73 |
48 #if !defined(NDEBUG) | 74 #if !defined(NDEBUG) |
49 void WriteFailedStderrSetupMessage(int out_fd) { | 75 void WriteFailedStderrSetupMessage(int out_fd) { |
50 const char* error_string = strerror(errno); | 76 const char* error_string = strerror(errno); |
51 static const char msg[] = | 77 static const char msg[] = |
52 "You have reproduced a puzzling issue.\n" | 78 "You have reproduced a puzzling issue.\n" |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 | 646 |
621 // Verify that the user pushed a policy. | 647 // Verify that the user pushed a policy. |
622 DCHECK(policy_); | 648 DCHECK(policy_); |
623 | 649 |
624 // Assemble the BPF filter program. | 650 // Assemble the BPF filter program. |
625 CodeGen* gen = new CodeGen(); | 651 CodeGen* gen = new CodeGen(); |
626 if (!gen) { | 652 if (!gen) { |
627 SANDBOX_DIE("Out of memory"); | 653 SANDBOX_DIE("Out of memory"); |
628 } | 654 } |
629 | 655 |
630 // If the architecture doesn't match SECCOMP_ARCH, disallow the | 656 bool has_unsafe_traps; |
631 // system call. | 657 Instruction* head = CompilePolicy(gen, &has_unsafe_traps); |
632 Instruction* tail; | |
633 Instruction* head = gen->MakeInstruction( | |
634 BPF_LD + BPF_W + BPF_ABS, | |
635 SECCOMP_ARCH_IDX, | |
636 tail = gen->MakeInstruction( | |
637 BPF_JMP + BPF_JEQ + BPF_K, | |
638 SECCOMP_ARCH, | |
639 NULL, | |
640 gen->MakeInstruction( | |
641 BPF_RET + BPF_K, | |
642 Kill("Invalid audit architecture in BPF filter")))); | |
643 | |
644 bool has_unsafe_traps = false; | |
645 { | |
646 // Evaluate all possible system calls and group their ErrorCodes into | |
647 // ranges of identical codes. | |
648 Ranges ranges; | |
649 FindRanges(&ranges); | |
650 | |
651 // Compile the system call ranges to an optimized BPF jumptable | |
652 Instruction* jumptable = | |
653 AssembleJumpTable(gen, ranges.begin(), ranges.end()); | |
654 | |
655 // If there is at least one UnsafeTrap() in our program, the entire sandbox | |
656 // is unsafe. We need to modify the program so that all non- | |
657 // SECCOMP_RET_ALLOW ErrorCodes are handled in user-space. This will then | |
658 // allow us to temporarily disable sandboxing rules inside of callbacks to | |
659 // UnsafeTrap(). | |
660 gen->Traverse(jumptable, CheckForUnsafeErrorCodes, &has_unsafe_traps); | |
661 | |
662 // Grab the system call number, so that we can implement jump tables. | |
663 Instruction* load_nr = | |
664 gen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, SECCOMP_NR_IDX); | |
665 | |
666 // If our BPF program has unsafe jumps, enable support for them. This | |
667 // test happens very early in the BPF filter program. Even before we | |
668 // consider looking at system call numbers. | |
669 // As support for unsafe jumps essentially defeats all the security | |
670 // measures that the sandbox provides, we print a big warning message -- | |
671 // and of course, we make sure to only ever enable this feature if it | |
672 // is actually requested by the sandbox policy. | |
673 if (has_unsafe_traps) { | |
674 if (Syscall::Call(-1) == -1 && errno == ENOSYS) { | |
675 SANDBOX_DIE( | |
676 "Support for UnsafeTrap() has not yet been ported to this " | |
677 "architecture"); | |
678 } | |
679 | |
680 if (!policy_->EvaluateSyscall(this, __NR_rt_sigprocmask) | |
681 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) || | |
682 !policy_->EvaluateSyscall(this, __NR_rt_sigreturn) | |
683 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) | |
684 #if defined(__NR_sigprocmask) | |
685 || | |
686 !policy_->EvaluateSyscall(this, __NR_sigprocmask) | |
687 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) | |
688 #endif | |
689 #if defined(__NR_sigreturn) | |
690 || | |
691 !policy_->EvaluateSyscall(this, __NR_sigreturn) | |
692 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) | |
693 #endif | |
694 ) { | |
695 SANDBOX_DIE( | |
696 "Invalid seccomp policy; if using UnsafeTrap(), you must " | |
697 "unconditionally allow sigreturn() and sigprocmask()"); | |
698 } | |
699 | |
700 if (!Trap::EnableUnsafeTrapsInSigSysHandler()) { | |
701 // We should never be able to get here, as UnsafeTrap() should never | |
702 // actually return a valid ErrorCode object unless the user set the | |
703 // CHROME_SANDBOX_DEBUGGING environment variable; and therefore, | |
704 // "has_unsafe_traps" would always be false. But better double-check | |
705 // than enabling dangerous code. | |
706 SANDBOX_DIE("We'd rather die than enable unsafe traps"); | |
707 } | |
708 gen->Traverse(jumptable, RedirectToUserspace, this); | |
709 | |
710 // Allow system calls, if they originate from our magic return address | |
711 // (which we can query by calling Syscall::Call(-1)). | |
712 uintptr_t syscall_entry_point = static_cast<uintptr_t>(Syscall::Call(-1)); | |
713 uint32_t low = static_cast<uint32_t>(syscall_entry_point); | |
714 #if __SIZEOF_POINTER__ > 4 | |
715 uint32_t hi = static_cast<uint32_t>(syscall_entry_point >> 32); | |
716 #endif | |
717 | |
718 // BPF cannot do native 64bit comparisons. On 64bit architectures, we | |
719 // have to compare both 32bit halves of the instruction pointer. If they | |
720 // match what we expect, we return ERR_ALLOWED. If either or both don't | |
721 // match, we continue evalutating the rest of the sandbox policy. | |
722 Instruction* escape_hatch = gen->MakeInstruction( | |
723 BPF_LD + BPF_W + BPF_ABS, | |
724 SECCOMP_IP_LSB_IDX, | |
725 gen->MakeInstruction( | |
726 BPF_JMP + BPF_JEQ + BPF_K, | |
727 low, | |
728 #if __SIZEOF_POINTER__ > 4 | |
729 gen->MakeInstruction( | |
730 BPF_LD + BPF_W + BPF_ABS, | |
731 SECCOMP_IP_MSB_IDX, | |
732 gen->MakeInstruction( | |
733 BPF_JMP + BPF_JEQ + BPF_K, | |
734 hi, | |
735 #endif | |
736 gen->MakeInstruction(BPF_RET + BPF_K, | |
737 ErrorCode(ErrorCode::ERR_ALLOWED)), | |
738 #if __SIZEOF_POINTER__ > 4 | |
739 load_nr)), | |
740 #endif | |
741 load_nr)); | |
742 gen->JoinInstructions(tail, escape_hatch); | |
743 } else { | |
744 gen->JoinInstructions(tail, load_nr); | |
745 } | |
746 tail = load_nr; | |
747 | |
748 // On Intel architectures, verify that system call numbers are in the | |
749 // expected number range. The older i386 and x86-64 APIs clear bit 30 | |
750 // on all system calls. The newer x32 API always sets bit 30. | |
751 #if defined(__i386__) || defined(__x86_64__) | |
752 Instruction* invalidX32 = gen->MakeInstruction( | |
753 BPF_RET + BPF_K, Kill("Illegal mixing of system call ABIs").err_); | |
754 Instruction* checkX32 = | |
755 #if defined(__x86_64__) && defined(__ILP32__) | |
756 gen->MakeInstruction( | |
757 BPF_JMP + BPF_JSET + BPF_K, 0x40000000, 0, invalidX32); | |
758 #else | |
759 gen->MakeInstruction( | |
760 BPF_JMP + BPF_JSET + BPF_K, 0x40000000, invalidX32, 0); | |
761 #endif | |
762 gen->JoinInstructions(tail, checkX32); | |
763 tail = checkX32; | |
764 #endif | |
765 | |
766 // Append jump table to our pre-amble | |
767 gen->JoinInstructions(tail, jumptable); | |
768 } | |
769 | 658 |
770 // Turn the DAG into a vector of instructions. | 659 // Turn the DAG into a vector of instructions. |
771 Program* program = new Program(); | 660 Program* program = new Program(); |
772 gen->Compile(head, program); | 661 gen->Compile(head, program); |
773 delete gen; | 662 delete gen; |
774 | 663 |
775 // Make sure compilation resulted in BPF program that executes | 664 // Make sure compilation resulted in BPF program that executes |
776 // correctly. Otherwise, there is an internal error in our BPF compiler. | 665 // correctly. Otherwise, there is an internal error in our BPF compiler. |
777 // There is really nothing the caller can do until the bug is fixed. | 666 // There is really nothing the caller can do until the bug is fixed. |
778 if (force_verification) { | 667 if (force_verification) { |
779 // Verification is expensive. We only perform this step, if we are | 668 // Verification is expensive. We only perform this step, if we are |
780 // compiled in debug mode, or if the caller explicitly requested | 669 // compiled in debug mode, or if the caller explicitly requested |
781 // verification. | 670 // verification. |
782 VerifyProgram(*program, has_unsafe_traps); | 671 VerifyProgram(*program, has_unsafe_traps); |
783 } | 672 } |
784 | 673 |
785 return program; | 674 return program; |
786 } | 675 } |
787 | 676 |
| 677 Instruction* SandboxBPF::CompilePolicy(CodeGen* gen, bool* has_unsafe_traps) { |
| 678 // A compiled policy consists of three logical parts: |
| 679 // 1. Check that the "arch" field matches the expected architecture. |
| 680 // 2. If the policy involves unsafe traps, check if the syscall was |
| 681 // invoked by Syscall::Call, and then allow it unconditionally. |
| 682 // 3. Check the system call number and jump to the appropriate compiled |
| 683 // system call policy number. |
| 684 return CheckArch( |
| 685 gen, MaybeAddEscapeHatch(gen, has_unsafe_traps, DispatchSyscall(gen))); |
| 686 } |
| 687 |
| 688 Instruction* SandboxBPF::CheckArch(CodeGen* gen, Instruction* passed) { |
| 689 // If the architecture doesn't match SECCOMP_ARCH, disallow the |
| 690 // system call. |
| 691 return gen->MakeInstruction( |
| 692 BPF_LD + BPF_W + BPF_ABS, |
| 693 SECCOMP_ARCH_IDX, |
| 694 gen->MakeInstruction( |
| 695 BPF_JMP + BPF_JEQ + BPF_K, |
| 696 SECCOMP_ARCH, |
| 697 passed, |
| 698 RetExpression(gen, |
| 699 Kill("Invalid audit architecture in BPF filter")))); |
| 700 } |
| 701 |
| 702 Instruction* SandboxBPF::MaybeAddEscapeHatch(CodeGen* gen, |
| 703 bool* has_unsafe_traps, |
| 704 Instruction* rest) { |
| 705 // If there is at least one UnsafeTrap() in our program, the entire sandbox |
| 706 // is unsafe. We need to modify the program so that all non- |
| 707 // SECCOMP_RET_ALLOW ErrorCodes are handled in user-space. This will then |
| 708 // allow us to temporarily disable sandboxing rules inside of callbacks to |
| 709 // UnsafeTrap(). |
| 710 *has_unsafe_traps = false; |
| 711 gen->Traverse(rest, CheckForUnsafeErrorCodes, has_unsafe_traps); |
| 712 if (!*has_unsafe_traps) { |
| 713 // If no unsafe traps, then simply return |rest|. |
| 714 return rest; |
| 715 } |
| 716 |
| 717 // If our BPF program has unsafe jumps, enable support for them. This |
| 718 // test happens very early in the BPF filter program. Even before we |
| 719 // consider looking at system call numbers. |
| 720 // As support for unsafe jumps essentially defeats all the security |
| 721 // measures that the sandbox provides, we print a big warning message -- |
| 722 // and of course, we make sure to only ever enable this feature if it |
| 723 // is actually requested by the sandbox policy. |
| 724 if (Syscall::Call(-1) == -1 && errno == ENOSYS) { |
| 725 SANDBOX_DIE( |
| 726 "Support for UnsafeTrap() has not yet been ported to this " |
| 727 "architecture"); |
| 728 } |
| 729 |
| 730 for (size_t i = 0; i < arraysize(kSyscallsRequiredForUnsafeTraps); ++i) { |
| 731 if (!policy_->EvaluateSyscall(this, kSyscallsRequiredForUnsafeTraps[i]) |
| 732 .Equals(ErrorCode(ErrorCode::ERR_ALLOWED))) { |
| 733 SANDBOX_DIE( |
| 734 "Policies that use UnsafeTrap() must unconditionally allow all " |
| 735 "required system calls"); |
| 736 } |
| 737 } |
| 738 |
| 739 if (!Trap::EnableUnsafeTrapsInSigSysHandler()) { |
| 740 // We should never be able to get here, as UnsafeTrap() should never |
| 741 // actually return a valid ErrorCode object unless the user set the |
| 742 // CHROME_SANDBOX_DEBUGGING environment variable; and therefore, |
| 743 // "has_unsafe_traps" would always be false. But better double-check |
| 744 // than enabling dangerous code. |
| 745 SANDBOX_DIE("We'd rather die than enable unsafe traps"); |
| 746 } |
| 747 gen->Traverse(rest, RedirectToUserspace, this); |
| 748 |
| 749 // Allow system calls, if they originate from our magic return address |
| 750 // (which we can query by calling Syscall::Call(-1)). |
| 751 uint64_t syscall_entry_point = |
| 752 static_cast<uint64_t>(static_cast<uintptr_t>(Syscall::Call(-1))); |
| 753 uint32_t low = static_cast<uint32_t>(syscall_entry_point); |
| 754 uint32_t hi = static_cast<uint32_t>(syscall_entry_point >> 32); |
| 755 |
| 756 // BPF cannot do native 64-bit comparisons, so we have to compare |
| 757 // both 32-bit halves of the instruction pointer. If they match what |
| 758 // we expect, we return ERR_ALLOWED. If either or both don't match, |
| 759 // we continue evalutating the rest of the sandbox policy. |
| 760 // |
| 761 // For simplicity, we check the full 64-bit instruction pointer even |
| 762 // on 32-bit architectures. |
| 763 return gen->MakeInstruction( |
| 764 BPF_LD + BPF_W + BPF_ABS, |
| 765 SECCOMP_IP_LSB_IDX, |
| 766 gen->MakeInstruction( |
| 767 BPF_JMP + BPF_JEQ + BPF_K, |
| 768 low, |
| 769 gen->MakeInstruction( |
| 770 BPF_LD + BPF_W + BPF_ABS, |
| 771 SECCOMP_IP_MSB_IDX, |
| 772 gen->MakeInstruction( |
| 773 BPF_JMP + BPF_JEQ + BPF_K, |
| 774 hi, |
| 775 RetExpression(gen, ErrorCode(ErrorCode::ERR_ALLOWED)), |
| 776 rest)), |
| 777 rest)); |
| 778 } |
| 779 |
| 780 Instruction* SandboxBPF::DispatchSyscall(CodeGen* gen) { |
| 781 // Evaluate all possible system calls and group their ErrorCodes into |
| 782 // ranges of identical codes. |
| 783 Ranges ranges; |
| 784 FindRanges(&ranges); |
| 785 |
| 786 // Compile the system call ranges to an optimized BPF jumptable |
| 787 Instruction* jumptable = AssembleJumpTable(gen, ranges.begin(), ranges.end()); |
| 788 |
| 789 // Grab the system call number, so that we can check it and then |
| 790 // execute the jump table. |
| 791 return gen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, |
| 792 SECCOMP_NR_IDX, |
| 793 CheckSyscallNumber(gen, jumptable)); |
| 794 } |
| 795 |
| 796 Instruction* SandboxBPF::CheckSyscallNumber(CodeGen* gen, Instruction* passed) { |
| 797 if (kIsIntel) { |
| 798 // On Intel architectures, verify that system call numbers are in the |
| 799 // expected number range. |
| 800 Instruction* invalidX32 = |
| 801 RetExpression(gen, Kill("Illegal mixing of system call ABIs")); |
| 802 if (kIsX32) { |
| 803 // The newer x32 API always sets bit 30. |
| 804 return gen->MakeInstruction( |
| 805 BPF_JMP + BPF_JSET + BPF_K, 0x40000000, passed, invalidX32); |
| 806 } else { |
| 807 // The older i386 and x86-64 APIs clear bit 30 on all system calls. |
| 808 return gen->MakeInstruction( |
| 809 BPF_JMP + BPF_JSET + BPF_K, 0x40000000, invalidX32, passed); |
| 810 } |
| 811 } |
| 812 |
| 813 // TODO(mdempsky): Similar validation for other architectures? |
| 814 return passed; |
| 815 } |
| 816 |
788 void SandboxBPF::VerifyProgram(const Program& program, bool has_unsafe_traps) { | 817 void SandboxBPF::VerifyProgram(const Program& program, bool has_unsafe_traps) { |
789 // If we previously rewrote the BPF program so that it calls user-space | 818 // If we previously rewrote the BPF program so that it calls user-space |
790 // whenever we return an "errno" value from the filter, then we have to | 819 // whenever we return an "errno" value from the filter, then we have to |
791 // wrap our system call evaluator to perform the same operation. Otherwise, | 820 // wrap our system call evaluator to perform the same operation. Otherwise, |
792 // the verifier would also report a mismatch in return codes. | 821 // the verifier would also report a mismatch in return codes. |
793 scoped_ptr<const RedirectToUserSpacePolicyWrapper> redirected_policy( | 822 scoped_ptr<const RedirectToUserSpacePolicyWrapper> redirected_policy( |
794 new RedirectToUserSpacePolicyWrapper(policy_.get())); | 823 new RedirectToUserSpacePolicyWrapper(policy_.get())); |
795 | 824 |
796 const char* err = NULL; | 825 const char* err = NULL; |
797 if (!Verifier::VerifyBPF(this, | 826 if (!Verifier::VerifyBPF(this, |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 | 1050 |
1022 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { | 1051 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { |
1023 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */); | 1052 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */); |
1024 } | 1053 } |
1025 | 1054 |
1026 ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) { | 1055 ErrorCode SandboxBPF::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) { |
1027 return Trap::MakeTrap(fnc, aux, false /* Unsafe Trap */); | 1056 return Trap::MakeTrap(fnc, aux, false /* Unsafe Trap */); |
1028 } | 1057 } |
1029 | 1058 |
1030 bool SandboxBPF::IsRequiredForUnsafeTrap(int sysno) { | 1059 bool SandboxBPF::IsRequiredForUnsafeTrap(int sysno) { |
1031 return (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn | 1060 for (size_t i = 0; i < arraysize(kSyscallsRequiredForUnsafeTraps); ++i) { |
1032 #if defined(__NR_sigprocmask) | 1061 if (sysno == kSyscallsRequiredForUnsafeTraps[i]) { |
1033 || | 1062 return true; |
1034 sysno == __NR_sigprocmask | 1063 } |
1035 #endif | 1064 } |
1036 #if defined(__NR_sigreturn) | 1065 return false; |
1037 || | |
1038 sysno == __NR_sigreturn | |
1039 #endif | |
1040 ); | |
1041 } | 1066 } |
1042 | 1067 |
1043 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { | 1068 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { |
1044 return Syscall::Call(args.nr, | 1069 return Syscall::Call(args.nr, |
1045 static_cast<intptr_t>(args.args[0]), | 1070 static_cast<intptr_t>(args.args[0]), |
1046 static_cast<intptr_t>(args.args[1]), | 1071 static_cast<intptr_t>(args.args[1]), |
1047 static_cast<intptr_t>(args.args[2]), | 1072 static_cast<intptr_t>(args.args[2]), |
1048 static_cast<intptr_t>(args.args[3]), | 1073 static_cast<intptr_t>(args.args[3]), |
1049 static_cast<intptr_t>(args.args[4]), | 1074 static_cast<intptr_t>(args.args[4]), |
1050 static_cast<intptr_t>(args.args[5])); | 1075 static_cast<intptr_t>(args.args[5])); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 } | 1130 } |
1106 } | 1131 } |
1107 | 1132 |
1108 ErrorCode SandboxBPF::Kill(const char* msg) { | 1133 ErrorCode SandboxBPF::Kill(const char* msg) { |
1109 return Trap(BPFFailure, const_cast<char*>(msg)); | 1134 return Trap(BPFFailure, const_cast<char*>(msg)); |
1110 } | 1135 } |
1111 | 1136 |
1112 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; | 1137 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; |
1113 | 1138 |
1114 } // namespace sandbox | 1139 } // namespace sandbox |
OLD | NEW |