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