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

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: Respond to jln's comments 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') | sandbox/linux/seccomp-bpf/verifier.cc » ('j') | 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 <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 if (cond.width_ == ErrorCode::TP_64BIT && sizeof(void*) != 8) {
887 SANDBOX_DIE("sandbox_bpf: 64-bit argument on 32-bit machine");
871 } 888 }
872 889
873 // BPF programs operate on 32bit entities. Load both halfs of the 64bit 890 Instruction* passed = RetExpression(gen, *cond.passed_);
874 // system call argument and then generate suitable conditional statements. 891 Instruction* failed = RetExpression(gen, *cond.failed_);
875 Instruction* msb_head = gen->MakeInstruction(
876 BPF_LD + BPF_W + BPF_ABS, SECCOMP_ARG_MSB_IDX(cond.argno_));
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 892
882 // Emit a suitable comparison statement. 893 // We want to emit code to check "(arg & mask) == value" where arg, mask, and
883 switch (cond.op_) { 894 // value are 64-bit values, but the BPF machine is only 32-bit. We implement
884 case ErrorCode::OP_EQUAL: 895 // this by independently testing the upper and lower 32-bits and continuing to
885 // Compare the least significant bits for equality 896 // |passed| if both evaluate true, or to |failed| if either evaluate false.
886 lsb_tail = gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 897 return CondExpressionHalf(
887 static_cast<uint32_t>(cond.value_), 898 gen,
888 RetExpression(gen, *cond.passed_), 899 cond,
889 RetExpression(gen, *cond.failed_)); 900 UpperHalf,
890 gen->JoinInstructions(lsb_head, lsb_tail); 901 CondExpressionHalf(gen, cond, LowerHalf, passed, failed),
902 failed);
903 }
891 904
892 // If we are looking at a 64bit argument, we need to also compare the 905 Instruction* SandboxBPF::CondExpressionHalf(CodeGen* gen,
893 // most significant bits. 906 const ErrorCode& cond,
894 if (cond.width_ == ErrorCode::TP_64BIT) { 907 ArgHalf half,
895 msb_tail = 908 Instruction* passed,
896 gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 909 Instruction* failed) {
897 static_cast<uint32_t>(cond.value_ >> 32), 910 if (cond.width_ == ErrorCode::TP_32BIT && half == UpperHalf) {
898 lsb_head, 911 // Special logic for sanity checking the upper 32-bits of 32-bit system
899 RetExpression(gen, *cond.failed_)); 912 // call arguments.
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 913
941 // If we are looking at a 64bit argument, we need to also check the bits 914 // TODO(mdempsky): Compile Unexpected64bitArgument() just per program.
942 // in the MSB half of the system call argument. 915 Instruction* invalid_64bit = RetExpression(gen, Unexpected64bitArgument());
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 916
992 // If we are looking at a 64bit argument, we need to also check the bits 917 const uint32_t upper = SECCOMP_ARG_MSB_IDX(cond.argno_);
993 // in the MSB half of the system call argument. 918 const uint32_t lower = SECCOMP_ARG_LSB_IDX(cond.argno_);
994 if (cond.width_ == ErrorCode::TP_64BIT) { 919
995 uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32); 920 if (sizeof(void*) == 4) {
996 if (!msb_bits) { 921 // On 32-bit platforms, the upper 32-bits should always be 0:
997 // No bits are set in the MSB half. The test will always fail. 922 // LDW [upper]
998 msb_head = lsb_head; 923 // JEQ 0, passed, invalid
999 } else { 924 return gen->MakeInstruction(
1000 msb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, 925 BPF_LD + BPF_W + BPF_ABS,
1001 msb_bits, 926 upper,
1002 RetExpression(gen, *cond.passed_), 927 gen->MakeInstruction(
1003 lsb_head); 928 BPF_JMP + BPF_JEQ + BPF_K, 0, passed, invalid_64bit));
1004 gen->JoinInstructions(msb_head, msb_tail); 929 }
1005 } 930
1006 } 931 // On 64-bit platforms, the upper 32-bits may be 0 or ~0; but we only allow
1007 break; 932 // ~0 if the sign bit of the lower 32-bits is set too:
1008 default: 933 // LDW [upper]
1009 // TODO(markus): Need to add support for OP_GREATER 934 // JEQ 0, passed, (next)
1010 SANDBOX_DIE("Not implemented"); 935 // JEQ ~0, (next), invalid
1011 break; 936 // LDW [lower]
937 // JSET (1<<31), passed, invalid
938 //
939 // TODO(mdempsky): The JSET instruction could perhaps jump to passed->next
940 // instead, as the first instruction of passed should be "LDW [lower]".
941 return gen->MakeInstruction(
942 BPF_LD + BPF_W + BPF_ABS,
943 upper,
944 gen->MakeInstruction(
945 BPF_JMP + BPF_JEQ + BPF_K,
946 0,
947 passed,
948 gen->MakeInstruction(
949 BPF_JMP + BPF_JEQ + BPF_K,
950 std::numeric_limits<uint32_t>::max(),
951 gen->MakeInstruction(
952 BPF_LD + BPF_W + BPF_ABS,
953 lower,
954 gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
955 1U << 31,
956 passed,
957 invalid_64bit)),
958 invalid_64bit)));
1012 } 959 }
1013 960
1014 // Ensure that we never pass a 64bit value, when we only expect a 32bit 961 const uint32_t idx = (half == UpperHalf) ? SECCOMP_ARG_MSB_IDX(cond.argno_)
1015 // value. This is somewhat complicated by the fact that on 64bit systems, 962 : SECCOMP_ARG_LSB_IDX(cond.argno_);
1016 // callers could legitimately pass in a non-zero value in the MSB, iff the 963 const uint32_t mask = (half == UpperHalf) ? cond.mask_ >> 32 : cond.mask_;
1017 // LSB has been sign-extended into the MSB. 964 const uint32_t value = (half == UpperHalf) ? cond.value_ >> 32 : cond.value_;
1018 if (cond.width_ == ErrorCode::TP_32BIT) {
1019 if (cond.value_ >> 32) {
1020 SANDBOX_DIE(
1021 "Invalid comparison of a 32bit system call argument "
1022 "against a 64bit constant; this test is always false.");
1023 }
1024 965
1025 Instruction* invalid_64bit = RetExpression(gen, Unexpected64bitArgument()); 966 // Emit a suitable instruction sequence for (arg & mask) == value.
1026 #if __SIZEOF_POINTER__ > 4 967
1027 invalid_64bit = gen->MakeInstruction( 968 // For (arg & 0) == 0, just return passed.
1028 BPF_JMP + BPF_JEQ + BPF_K, 969 if (mask == 0) {
1029 0xFFFFFFFF, 970 CHECK_EQ(0U, value);
1030 gen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 971 return passed;
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 } 972 }
1043 973
1044 return msb_head; 974 // For (arg & ~0) == value, emit:
975 // LDW [idx]
976 // JEQ value, passed, failed
977 if (mask == std::numeric_limits<uint32_t>::max()) {
978 return gen->MakeInstruction(
979 BPF_LD + BPF_W + BPF_ABS,
980 idx,
981 gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed));
982 }
983
984 // For (arg & mask) == 0, emit:
985 // LDW [idx]
986 // JSET mask, failed, passed
987 // (Note: failed and passed are intentionally swapped.)
988 if (value == 0) {
989 return gen->MakeInstruction(
990 BPF_LD + BPF_W + BPF_ABS,
991 idx,
992 gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, mask, failed, passed));
993 }
994
995 // For (arg & x) == x where x is a single-bit value, emit:
996 // LDW [idx]
997 // JSET mask, passed, failed
998 if (mask == value && HasExactlyOneBit(mask)) {
999 return gen->MakeInstruction(
1000 BPF_LD + BPF_W + BPF_ABS,
1001 idx,
1002 gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, mask, passed, failed));
1003 }
1004
1005 // Generic fallback:
1006 // LDW [idx]
1007 // AND mask
1008 // JEQ value, passed, failed
1009 return gen->MakeInstruction(
1010 BPF_LD + BPF_W + BPF_ABS,
1011 idx,
1012 gen->MakeInstruction(
1013 BPF_ALU + BPF_AND + BPF_K,
1014 mask,
1015 gen->MakeInstruction(
1016 BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed)));
1045 } 1017 }
1046 1018
1047 ErrorCode SandboxBPF::Unexpected64bitArgument() { 1019 ErrorCode SandboxBPF::Unexpected64bitArgument() {
1048 return Kill("Unexpected 64bit argument detected"); 1020 return Kill("Unexpected 64bit argument detected");
1049 } 1021 }
1050 1022
1051 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) { 1023 ErrorCode SandboxBPF::Trap(Trap::TrapFnc fnc, const void* aux) {
1052 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */); 1024 return Trap::MakeTrap(fnc, aux, true /* Safe Trap */);
1053 } 1025 }
1054 1026
(...skipping 17 matching lines...) Expand all
1072 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) { 1044 intptr_t SandboxBPF::ForwardSyscall(const struct arch_seccomp_data& args) {
1073 return Syscall::Call(args.nr, 1045 return Syscall::Call(args.nr,
1074 static_cast<intptr_t>(args.args[0]), 1046 static_cast<intptr_t>(args.args[0]),
1075 static_cast<intptr_t>(args.args[1]), 1047 static_cast<intptr_t>(args.args[1]),
1076 static_cast<intptr_t>(args.args[2]), 1048 static_cast<intptr_t>(args.args[2]),
1077 static_cast<intptr_t>(args.args[3]), 1049 static_cast<intptr_t>(args.args[3]),
1078 static_cast<intptr_t>(args.args[4]), 1050 static_cast<intptr_t>(args.args[4]),
1079 static_cast<intptr_t>(args.args[5])); 1051 static_cast<intptr_t>(args.args[5]));
1080 } 1052 }
1081 1053
1054 ErrorCode SandboxBPF::CondMaskedEqual(int argno,
1055 ErrorCode::ArgType width,
1056 uint64_t mask,
1057 uint64_t value,
1058 const ErrorCode& passed,
1059 const ErrorCode& failed) {
1060 return ErrorCode(argno,
1061 width,
1062 mask,
1063 value,
1064 &*conds_->insert(passed).first,
1065 &*conds_->insert(failed).first);
1066 }
1067
1082 ErrorCode SandboxBPF::Cond(int argno, 1068 ErrorCode SandboxBPF::Cond(int argno,
1083 ErrorCode::ArgType width, 1069 ErrorCode::ArgType width,
1084 ErrorCode::Operation op, 1070 ErrorCode::Operation op,
1085 uint64_t value, 1071 uint64_t value,
1086 const ErrorCode& passed, 1072 const ErrorCode& passed,
1087 const ErrorCode& failed) { 1073 const ErrorCode& failed) {
1088 return ErrorCode(argno, 1074 // CondExpression() currently rejects mask==0 as invalid, but there are
1089 width, 1075 // SandboxBPF unit tests that (questionably) expect OP_HAS_{ANY,ALL}_BITS to
1090 op, 1076 // work with value==0. To keep those tests working for now, we specially
1091 value, 1077 // convert value==0 here.
jln (very slow on Chromium) 2014/09/04 21:45:05 Should this comment be below (inside the switch) ?
1092 &*conds_->insert(passed).first, 1078
1093 &*conds_->insert(failed).first); 1079 switch (op) {
1080 case ErrorCode::OP_EQUAL: {
1081 // Convert to "(arg & ~0) == value".
1082 const uint64_t mask = (width == ErrorCode::TP_64BIT)
1083 ? std::numeric_limits<uint64_t>::max()
1084 : std::numeric_limits<uint32_t>::max();
1085 return CondMaskedEqual(argno, width, mask, value, passed, failed);
1086 }
1087
1088 case ErrorCode::OP_HAS_ALL_BITS:
1089 if (value == 0) {
1090 // Always passes.
1091 return passed;
1092 }
1093 // Convert to "(arg & value) == value".
1094 return CondMaskedEqual(argno, width, value, value, passed, failed);
1095
1096 case ErrorCode::OP_HAS_ANY_BITS:
1097 if (value == 0) {
1098 // Always fails.
1099 return failed;
1100 }
1101 // Convert to "(arg & value) == 0", but swap passed and failed.
1102 return CondMaskedEqual(argno, width, value, 0, failed, passed);
1103
1104 default:
1105 SANDBOX_DIE("Not implemented");
1106 }
1094 } 1107 }
1095 1108
1096 ErrorCode SandboxBPF::Kill(const char* msg) { 1109 ErrorCode SandboxBPF::Kill(const char* msg) {
1097 return Trap(BPFFailure, const_cast<char*>(msg)); 1110 return Trap(BPFFailure, const_cast<char*>(msg));
1098 } 1111 }
1099 1112
1100 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN; 1113 SandboxBPF::SandboxStatus SandboxBPF::status_ = STATUS_UNKNOWN;
1101 1114
1102 } // namespace sandbox 1115 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | sandbox/linux/seccomp-bpf/verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698