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

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

Issue 530133003: bpf_dsl: support arbitrary (arg & mask) == val expressions (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add unit tests to sandbox_bpf_unittest.cc 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
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 <string.h> 15 #include <string.h>
16 #include <sys/prctl.h> 16 #include <sys/prctl.h>
17 #include <sys/stat.h> 17 #include <sys/stat.h>
18 #include <sys/syscall.h> 18 #include <sys/syscall.h>
19 #include <sys/types.h> 19 #include <sys/types.h>
20 #include <time.h> 20 #include <time.h>
21 #include <unistd.h> 21 #include <unistd.h>
22 22
23 #include <limits>
24
23 #include "base/compiler_specific.h" 25 #include "base/compiler_specific.h"
24 #include "base/logging.h" 26 #include "base/logging.h"
25 #include "base/macros.h" 27 #include "base/macros.h"
26 #include "base/memory/scoped_ptr.h" 28 #include "base/memory/scoped_ptr.h"
27 #include "base/posix/eintr_wrapper.h" 29 #include "base/posix/eintr_wrapper.h"
28 #include "sandbox/linux/seccomp-bpf/codegen.h" 30 #include "sandbox/linux/seccomp-bpf/codegen.h"
29 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" 31 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
30 #include "sandbox/linux/seccomp-bpf/syscall.h" 32 #include "sandbox/linux/seccomp-bpf/syscall.h"
31 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" 33 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
32 #include "sandbox/linux/seccomp-bpf/verifier.h" 34 #include "sandbox/linux/seccomp-bpf/verifier.h"
33 #include "sandbox/linux/services/linux_syscalls.h" 35 #include "sandbox/linux/services/linux_syscalls.h"
34 36
35 namespace sandbox { 37 namespace sandbox {
36 38
37 namespace { 39 namespace {
38 40
39 const int kExpectedExitCode = 100; 41 const int kExpectedExitCode = 100;
40 42
41 int popcount(uint32_t x) { 43 bool HasExactlyOneBit(uint64_t x) {
42 return __builtin_popcount(x); 44 // Common trick; e.g., see http://stackoverflow.com/a/108329.
45 return x != 0 && (x & (x - 1)) == 0;
43 } 46 }
44 47
45 #if !defined(NDEBUG) 48 #if !defined(NDEBUG)
46 void WriteFailedStderrSetupMessage(int out_fd) { 49 void WriteFailedStderrSetupMessage(int out_fd) {
47 const char* error_string = strerror(errno); 50 const char* error_string = strerror(errno);
48 static const char msg[] = 51 static const char msg[] =
49 "You have reproduced a puzzling issue.\n" 52 "You have reproduced a puzzling issue.\n"
50 "Please, report to crbug.com/152530!\n" 53 "Please, report to crbug.com/152530!\n"
51 "Failed to set up stderr: "; 54 "Failed to set up stderr: ";
52 if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg) - 1)) > 0 && error_string && 55 if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg) - 1)) > 0 && error_string &&
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 858
856 Instruction* SandboxBPF::RetExpression(CodeGen* gen, const ErrorCode& err) { 859 Instruction* SandboxBPF::RetExpression(CodeGen* gen, const ErrorCode& err) {
857 if (err.error_type_ == ErrorCode::ET_COND) { 860 if (err.error_type_ == ErrorCode::ET_COND) {
858 return CondExpression(gen, err); 861 return CondExpression(gen, err);
859 } else { 862 } else {
860 return gen->MakeInstruction(BPF_RET + BPF_K, err); 863 return gen->MakeInstruction(BPF_RET + BPF_K, err);
861 } 864 }
862 } 865 }
863 866
864 Instruction* SandboxBPF::CondExpression(CodeGen* gen, const ErrorCode& cond) { 867 Instruction* SandboxBPF::CondExpression(CodeGen* gen, const ErrorCode& cond) {
865 // We can only inspect the six system call arguments that are passed in 868 // Sanity check that |cond| makes sense.
866 // CPU registers.
867 if (cond.argno_ < 0 || cond.argno_ >= 6) { 869 if (cond.argno_ < 0 || cond.argno_ >= 6) {
868 SANDBOX_DIE( 870 SANDBOX_DIE("sandbox_bpf: invalid argument number");
869 "Internal compiler error; invalid argument number " 871 }
870 "encountered"); 872 if (cond.width_ != ErrorCode::TP_32BIT &&
873 cond.width_ != ErrorCode::TP_64BIT) {
874 SANDBOX_DIE("sandbox_bpf: invalid argument width");
875 }
876 if (cond.mask_ == 0) {
877 SANDBOX_DIE("sandbox_bpf: zero mask is invalid");
878 }
879 if ((cond.value_ & cond.mask_) != cond.value_) {
880 SANDBOX_DIE("sandbox_bpf: value contains masked out bits");
881 }
882 if (cond.width_ == ErrorCode::TP_32BIT &&
883 ((cond.mask_ >> 32) != 0 || (cond.value_ >> 32) != 0)) {
884 SANDBOX_DIE("sandbox_bpf: test exceeds argument size");
885 }
886 // TODO(mdempsky): Reject TP_64BIT on 32-bit platforms. For now we allow it
887 // because some SandboxBPF unit tests exercise it.
jln (very slow on Chromium) 2014/09/04 21:45:06 TP_64BIT is actually the right default most of the
888
889 Instruction* passed = RetExpression(gen, *cond.passed_);
890 Instruction* failed = RetExpression(gen, *cond.failed_);
891
892 // We want to emit code to check "(arg & mask) == value" where arg, mask, and
893 // value are 64-bit values, but the BPF machine is only 32-bit. We implement
894 // this by independently testing the upper and lower 32-bits and continuing to
895 // |passed| if both evaluate true, or to |failed| if either evaluate false.
896 return CondExpressionHalf(
897 gen,
898 cond,
899 UpperHalf,
900 CondExpressionHalf(gen, cond, LowerHalf, passed, failed),
901 failed);
902 }
903
904 Instruction* SandboxBPF::CondExpressionHalf(CodeGen* gen,
905 const ErrorCode& cond,
906 ArgHalf half,
907 Instruction* passed,
908 Instruction* failed) {
909 if (cond.width_ == ErrorCode::TP_32BIT && half == UpperHalf) {
910 // Special logic for sanity checking the upper 32-bits of 32-bit system
911 // call arguments.
912
913 // TODO(mdempsky): Compile Unexpected64bitArgument() just per program.
914 Instruction* invalid_64bit = RetExpression(gen, Unexpected64bitArgument());
915
916 const uint32_t upper = SECCOMP_ARG_MSB_IDX(cond.argno_);
917 const uint32_t lower = SECCOMP_ARG_LSB_IDX(cond.argno_);
918
919 if (sizeof(void*) == 4) {
920 // On 32-bit platforms, the upper 32-bits should always be 0:
921 // LDW [upper]
922 // JEQ 0, passed, invalid
923 return gen->MakeInstruction(
924 BPF_LD + BPF_W + BPF_ABS,
925 upper,
926 gen->MakeInstruction(
927 BPF_JMP + BPF_JEQ + BPF_K, 0, passed, invalid_64bit));
928 }
929
930 // On 64-bit platforms, the upper 32-bits may be 0 or ~0; but we only allow
931 // ~0 if the sign bit of the lower 32-bits is set too:
932 // LDW [upper]
933 // JEQ 0, passed, (next)
934 // JEQ ~0, (next), invalid
935 // LDW [lower]
936 // JSET (1<<31), passed, invalid
937 //
938 // TODO(mdempsky): The JSET instruction could perhaps jump to passed->next
939 // instead, as the first instruction of passed should be "LDW [lower]".
940 return gen->MakeInstruction(
941 BPF_LD + BPF_W + BPF_ABS,
942 upper,
943 gen->MakeInstruction(
944 BPF_JMP + BPF_JEQ + BPF_K,
945 0,
946 passed,
947 gen->MakeInstruction(
948 BPF_JMP + BPF_JEQ + BPF_K,
949 std::numeric_limits<uint32_t>::max(),
950 gen->MakeInstruction(
951 BPF_LD + BPF_W + BPF_ABS,
952 lower,
953 gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
954 1U << 31,
955 passed,
956 invalid_64bit)),
957 invalid_64bit)));
871 } 958 }
872 959
873 // BPF programs operate on 32bit entities. Load both halfs of the 64bit 960 const uint32_t idx = (half == UpperHalf) ? SECCOMP_ARG_MSB_IDX(cond.argno_)
874 // system call argument and then generate suitable conditional statements. 961 : SECCOMP_ARG_LSB_IDX(cond.argno_);
875 Instruction* msb_head = gen->MakeInstruction( 962 const uint32_t mask = (half == UpperHalf) ? cond.mask_ >> 32 : cond.mask_;
876 BPF_LD + BPF_W + BPF_ABS, SECCOMP_ARG_MSB_IDX(cond.argno_)); 963 const uint32_t value = (half == UpperHalf) ? cond.value_ >> 32 : cond.value_;
877 Instruction* msb_tail = msb_head;
878 Instruction* lsb_head = gen->MakeInstruction(
879 BPF_LD + BPF_W + BPF_ABS, SECCOMP_ARG_LSB_IDX(cond.argno_));
880 Instruction* lsb_tail = lsb_head;
881 964
882 // Emit a suitable comparison statement. 965 // Emit a suitable instruction sequence for (arg & mask) == value.
883 switch (cond.op_) {
884 case ErrorCode::OP_EQUAL:
885 // Compare the least significant bits for equality
886 lsb_tail = gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K,
887 static_cast<uint32_t>(cond.value_),
888 RetExpression(gen, *cond.passed_),
889 RetExpression(gen, *cond.failed_));
890 gen->JoinInstructions(lsb_head, lsb_tail);
891 966
892 // If we are looking at a 64bit argument, we need to also compare the 967 // For (arg & 0) == 0, just return passed.
893 // most significant bits. 968 if (mask == 0) {
894 if (cond.width_ == ErrorCode::TP_64BIT) { 969 CHECK_EQ(0U, value);
895 msb_tail = 970 return passed;
896 gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K,
897 static_cast<uint32_t>(cond.value_ >> 32),
898 lsb_head,
899 RetExpression(gen, *cond.failed_));
900 gen->JoinInstructions(msb_head, msb_tail);
901 }
902 break;
903 case ErrorCode::OP_HAS_ALL_BITS:
904 // Check the bits in the LSB half of the system call argument. Our
905 // OP_HAS_ALL_BITS operator passes, iff all of the bits are set. This is
906 // different from the kernel's BPF_JSET operation which passes, if any of
907 // the bits are set.
908 // Of course, if there is only a single set bit (or none at all), then
909 // things get easier.
910 {
911 uint32_t lsb_bits = static_cast<uint32_t>(cond.value_);
912 int lsb_bit_count = popcount(lsb_bits);
913 if (lsb_bit_count == 0) {
914 // No bits are set in the LSB half. The test will always pass.
915 lsb_head = RetExpression(gen, *cond.passed_);
916 lsb_tail = NULL;
917 } else if (lsb_bit_count == 1) {
918 // Exactly one bit is set in the LSB half. We can use the BPF_JSET
919 // operator.
920 lsb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
921 lsb_bits,
922 RetExpression(gen, *cond.passed_),
923 RetExpression(gen, *cond.failed_));
924 gen->JoinInstructions(lsb_head, lsb_tail);
925 } else {
926 // More than one bit is set in the LSB half. We need to combine
927 // BPF_AND and BPF_JEQ to test whether all of these bits are in fact
928 // set in the system call argument.
929 gen->JoinInstructions(
930 lsb_head,
931 gen->MakeInstruction(BPF_ALU + BPF_AND + BPF_K,
932 lsb_bits,
933 lsb_tail = gen->MakeInstruction(
934 BPF_JMP + BPF_JEQ + BPF_K,
935 lsb_bits,
936 RetExpression(gen, *cond.passed_),
937 RetExpression(gen, *cond.failed_))));
938 }
939 }
940
941 // If we are looking at a 64bit argument, we need to also check the bits
942 // in the MSB half of the system call argument.
943 if (cond.width_ == ErrorCode::TP_64BIT) {
944 uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32);
945 int msb_bit_count = popcount(msb_bits);
946 if (msb_bit_count == 0) {
947 // No bits are set in the MSB half. The test will always pass.
948 msb_head = lsb_head;
949 } else if (msb_bit_count == 1) {
950 // Exactly one bit is set in the MSB half. We can use the BPF_JSET
951 // operator.
952 msb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
953 msb_bits,
954 lsb_head,
955 RetExpression(gen, *cond.failed_));
956 gen->JoinInstructions(msb_head, msb_tail);
957 } else {
958 // More than one bit is set in the MSB half. We need to combine
959 // BPF_AND and BPF_JEQ to test whether all of these bits are in fact
960 // set in the system call argument.
961 gen->JoinInstructions(
962 msb_head,
963 gen->MakeInstruction(
964 BPF_ALU + BPF_AND + BPF_K,
965 msb_bits,
966 gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K,
967 msb_bits,
968 lsb_head,
969 RetExpression(gen, *cond.failed_))));
970 }
971 }
972 break;
973 case ErrorCode::OP_HAS_ANY_BITS:
974 // Check the bits in the LSB half of the system call argument. Our
975 // OP_HAS_ANY_BITS operator passes, iff any of the bits are set. This maps
976 // nicely to the kernel's BPF_JSET operation.
977 {
978 uint32_t lsb_bits = static_cast<uint32_t>(cond.value_);
979 if (!lsb_bits) {
980 // No bits are set in the LSB half. The test will always fail.
981 lsb_head = RetExpression(gen, *cond.failed_);
982 lsb_tail = NULL;
983 } else {
984 lsb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
985 lsb_bits,
986 RetExpression(gen, *cond.passed_),
987 RetExpression(gen, *cond.failed_));
988 gen->JoinInstructions(lsb_head, lsb_tail);
989 }
990 }
991
992 // If we are looking at a 64bit argument, we need to also check the bits
993 // in the MSB half of the system call argument.
994 if (cond.width_ == ErrorCode::TP_64BIT) {
995 uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32);
996 if (!msb_bits) {
997 // No bits are set in the MSB half. The test will always fail.
998 msb_head = lsb_head;
999 } else {
1000 msb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
1001 msb_bits,
1002 RetExpression(gen, *cond.passed_),
1003 lsb_head);
1004 gen->JoinInstructions(msb_head, msb_tail);
1005 }
1006 }
1007 break;
1008 default:
1009 // TODO(markus): Need to add support for OP_GREATER
1010 SANDBOX_DIE("Not implemented");
1011 break;
1012 } 971 }
1013 972
1014 // Ensure that we never pass a 64bit value, when we only expect a 32bit 973 // For (arg & ~0) == value, emit:
1015 // value. This is somewhat complicated by the fact that on 64bit systems, 974 // LDW [idx]
1016 // callers could legitimately pass in a non-zero value in the MSB, iff the 975 // JEQ value, passed, failed
1017 // LSB has been sign-extended into the MSB. 976 if (mask == std::numeric_limits<uint32_t>::max()) {
1018 if (cond.width_ == ErrorCode::TP_32BIT) { 977 return gen->MakeInstruction(
1019 if (cond.value_ >> 32) { 978 BPF_LD + BPF_W + BPF_ABS,
1020 SANDBOX_DIE( 979 idx,
1021 "Invalid comparison of a 32bit system call argument " 980 gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed));
1022 "against a 64bit constant; this test is always false.");
1023 }
1024
1025 Instruction* invalid_64bit = RetExpression(gen, Unexpected64bitArgument());
1026 #if __SIZEOF_POINTER__ > 4
1027 invalid_64bit = gen->MakeInstruction(
1028 BPF_JMP + BPF_JEQ + BPF_K,
1029 0xFFFFFFFF,
1030 gen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS,
1031 SECCOMP_ARG_LSB_IDX(cond.argno_),
1032 gen->MakeInstruction(BPF_JMP + BPF_JGE + BPF_K,
1033 0x80000000,
1034 lsb_head,
1035 invalid_64bit)),
1036 invalid_64bit);
1037 #endif
1038 gen->JoinInstructions(
1039 msb_tail,
1040 gen->MakeInstruction(
1041 BPF_JMP + BPF_JEQ + BPF_K, 0, lsb_head, invalid_64bit));
1042 } 981 }
1043 982
1044 return msb_head; 983 // For (arg & mask) == 0, emit:
984 // LDW [idx]
985 // JSET mask, failed, passed
986 // (Note: failed and passed are intentionally swapped.)
987 if (value == 0) {
988 return gen->MakeInstruction(
989 BPF_LD + BPF_W + BPF_ABS,
990 idx,
991 gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, mask, failed, passed));
992 }
993
994 // For (arg & x) == x where x is a single-bit value, emit:
995 // LDW [idx]
996 // JSET mask, passed, failed
997 if (mask == value && HasExactlyOneBit(mask)) {
998 return gen->MakeInstruction(
999 BPF_LD + BPF_W + BPF_ABS,
1000 idx,
1001 gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, mask, passed, failed));
1002 }
1003
1004 // Generic fallback:
1005 // LDW [idx]
1006 // AND mask
1007 // JEQ value, passed, failed
1008 return gen->MakeInstruction(
1009 BPF_LD + BPF_W + BPF_ABS,
1010 idx,
1011 gen->MakeInstruction(
1012 BPF_ALU + BPF_AND + BPF_K,
1013 mask,
1014 gen->MakeInstruction(
1015 BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed)));
1045 } 1016 }
1046 1017
1047 ErrorCode SandboxBPF::Unexpected64bitArgument() { 1018 ErrorCode SandboxBPF::Unexpected64bitArgument() {
1048 return Kill("Unexpected 64bit argument detected"); 1019 return Kill("Unexpected 64bit argument detected");
1049 } 1020 }
1050 1021
1051 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { 1022 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) {
1052 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */); 1023 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */);
1053 } 1024 }
1054 1025
(...skipping 17 matching lines...) Expand all
1072 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { 1043 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) {
1073 return Syscall::Call(args.nr, 1044 return Syscall::Call(args.nr,
1074 static_cast<intptr_t>(args.args[0]), 1045 static_cast<intptr_t>(args.args[0]),
1075 static_cast<intptr_t>(args.args[1]), 1046 static_cast<intptr_t>(args.args[1]),
1076 static_cast<intptr_t>(args.args[2]), 1047 static_cast<intptr_t>(args.args[2]),
1077 static_cast<intptr_t>(args.args[3]), 1048 static_cast<intptr_t>(args.args[3]),
1078 static_cast<intptr_t>(args.args[4]), 1049 static_cast<intptr_t>(args.args[4]),
1079 static_cast<intptr_t>(args.args[5])); 1050 static_cast<intptr_t>(args.args[5]));
1080 } 1051 }
1081 1052
1053 ErrorCode SandboxBPF::CondMaskedEqual(int argno,
1054 ErrorCode::ArgType width,
1055 uint64_t mask,
1056 uint64_t value,
1057 const ErrorCode& passed,
1058 const ErrorCode& failed) {
1059 return ErrorCode(argno,
1060 width,
1061 mask,
1062 value,
1063 &*conds_->insert(passed).first,
1064 &*conds_->insert(failed).first);
1065 }
1066
1082 ErrorCode SandboxBPF::Cond(int argno, 1067 ErrorCode SandboxBPF::Cond(int argno,
1083 ErrorCode::ArgType width, 1068 ErrorCode::ArgType width,
1084 ErrorCode::Operation op, 1069 ErrorCode::Operation op,
1085 uint64_t value, 1070 uint64_t value,
1086 const ErrorCode& passed, 1071 const ErrorCode& passed,
1087 const ErrorCode& failed) { 1072 const ErrorCode& failed) {
1088 return ErrorCode(argno, 1073 // CondExpression() currently rejects mask==0 as invalid, but there are
1089 width, 1074 // SandboxBPF unit tests that (questionably) expect OP_HAS_{ANY,ALL}_BITS to
1090 op, 1075 // work with value==0. To keep those tests working for now, we specially
1091 value, 1076 // convert value==0 here.
1092 &*conds_->insert(passed).first, 1077
1093 &*conds_->insert(failed).first); 1078 switch (op) {
1079 case ErrorCode::OP_EQUAL: {
1080 // Convert to "(arg & ~0) == value".
1081 const uint64_t mask = (width == ErrorCode::TP_64BIT)
1082 ? std::numeric_limits<uint64_t>::max()
1083 : std::numeric_limits<uint32_t>::max();
1084 return CondMaskedEqual(argno, width, mask, value, passed, failed);
1085 }
1086
1087 case ErrorCode::OP_HAS_ALL_BITS:
1088 if (value == 0) {
1089 // Always passes.
1090 return passed;
1091 }
1092 // Convert to "(arg & value) == value".
1093 return CondMaskedEqual(argno, width, value, value, passed, failed);
1094
1095 case ErrorCode::OP_HAS_ANY_BITS:
1096 if (value == 0) {
1097 // Always fails.
1098 return failed;
1099 }
1100 // Convert to "(arg & value) == 0", but swap passed and failed.
1101 return CondMaskedEqual(argno, width, value, 0, failed, passed);
1102
1103 default:
1104 SANDBOX_DIE("Not implemented");
1105 }
1094 } 1106 }
1095 1107
1096 ErrorCode SandboxBPF::Kill(const char* msg) { 1108 ErrorCode SandboxBPF::Kill(const char* msg) {
1097 return Trap(BPFFailure, const_cast<char*>(msg)); 1109 return Trap(BPFFailure, const_cast<char*>(msg));
1098 } 1110 }
1099 1111
1100 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; 1112 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN;
1101 1113
1102 } // namespace sandbox 1114 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698