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

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: Respond to jln feedback 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 #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
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
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
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
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