Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Side by Side Diff: sandbox/linux/seccomp-bpf/sandbox_bpf.cc

Issue 568053005: Split AssembleFilter into comprehensible chunks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698