| 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 |