| 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/bpf_dsl/bpf_dsl.h" | 5 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> |
| 8 #include <pthread.h> | 9 #include <pthread.h> |
| 9 #include <sched.h> | 10 #include <sched.h> |
| 10 #include <signal.h> | 11 #include <signal.h> |
| 11 #include <sys/prctl.h> | 12 #include <sys/prctl.h> |
| 12 #include <sys/ptrace.h> | 13 #include <sys/ptrace.h> |
| 13 #include <sys/syscall.h> | 14 #include <sys/syscall.h> |
| 14 #include <sys/time.h> | 15 #include <sys/time.h> |
| 15 #include <sys/types.h> | 16 #include <sys/types.h> |
| 16 #include <sys/utsname.h> | 17 #include <sys/utsname.h> |
| 17 #include <unistd.h> | 18 #include <unistd.h> |
| 18 #include <sys/socket.h> | 19 #include <sys/socket.h> |
| 19 | 20 |
| 20 #if defined(ANDROID) | 21 #if defined(ANDROID) |
| 21 // Work-around for buggy headers in Android's NDK | 22 // Work-around for buggy headers in Android's NDK |
| 22 #define __user | 23 #define __user |
| 23 #endif | 24 #endif |
| 24 #include <linux/futex.h> | 25 #include <linux/futex.h> |
| 25 | 26 |
| 26 #include "base/bind.h" | 27 #include "base/bind.h" |
| 27 #include "base/logging.h" | 28 #include "base/logging.h" |
| 28 #include "base/macros.h" | 29 #include "base/macros.h" |
| 29 #include "base/memory/scoped_ptr.h" | 30 #include "base/memory/scoped_ptr.h" |
| 30 #include "base/posix/eintr_wrapper.h" | 31 #include "base/posix/eintr_wrapper.h" |
| 31 #include "base/synchronization/waitable_event.h" | 32 #include "base/synchronization/waitable_event.h" |
| 32 #include "base/threading/thread.h" | 33 #include "base/threading/thread.h" |
| 33 #include "build/build_config.h" | 34 #include "build/build_config.h" |
| 34 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" | 35 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
| 35 #include "sandbox/linux/seccomp-bpf/die.h" | 36 #include "sandbox/linux/seccomp-bpf/die.h" |
| 36 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" | 37 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" |
| 38 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
| 37 #include "sandbox/linux/seccomp-bpf/syscall.h" | 39 #include "sandbox/linux/seccomp-bpf/syscall.h" |
| 38 #include "sandbox/linux/seccomp-bpf/trap.h" | 40 #include "sandbox/linux/seccomp-bpf/trap.h" |
| 39 #include "sandbox/linux/services/broker_process.h" | 41 #include "sandbox/linux/services/broker_process.h" |
| 40 #include "sandbox/linux/services/linux_syscalls.h" | 42 #include "sandbox/linux/services/linux_syscalls.h" |
| 41 #include "sandbox/linux/tests/scoped_temporary_file.h" | 43 #include "sandbox/linux/tests/scoped_temporary_file.h" |
| 42 #include "sandbox/linux/tests/unit_tests.h" | 44 #include "sandbox/linux/tests/unit_tests.h" |
| 43 #include "testing/gtest/include/gtest/gtest.h" | 45 #include "testing/gtest/include/gtest/gtest.h" |
| 44 | 46 |
| 45 // Workaround for Android's prctl.h file. | 47 // Workaround for Android's prctl.h file. |
| 46 #ifndef PR_GET_ENDIAN | 48 #ifndef PR_GET_ENDIAN |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 // that explicitly walks through all these steps. | 102 // that explicitly walks through all these steps. |
| 101 | 103 |
| 102 intptr_t IncreaseCounter(const struct arch_seccomp_data& args, void* aux) { | 104 intptr_t IncreaseCounter(const struct arch_seccomp_data& args, void* aux) { |
| 103 BPF_ASSERT(aux); | 105 BPF_ASSERT(aux); |
| 104 int* counter = static_cast<int*>(aux); | 106 int* counter = static_cast<int*>(aux); |
| 105 return (*counter)++; | 107 return (*counter)++; |
| 106 } | 108 } |
| 107 | 109 |
| 108 class VerboseAPITestingPolicy : public SandboxBPFDSLPolicy { | 110 class VerboseAPITestingPolicy : public SandboxBPFDSLPolicy { |
| 109 public: | 111 public: |
| 110 VerboseAPITestingPolicy(int* counter_ptr) : counter_ptr_(counter_ptr) {} | 112 explicit VerboseAPITestingPolicy(int* counter_ptr) |
| 113 : counter_ptr_(counter_ptr) {} |
| 111 virtual ~VerboseAPITestingPolicy() {} | 114 virtual ~VerboseAPITestingPolicy() {} |
| 112 | 115 |
| 113 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { | 116 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { |
| 114 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 117 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 115 if (sysno == __NR_uname) { | 118 if (sysno == __NR_uname) { |
| 116 return Trap(IncreaseCounter, counter_ptr_); | 119 return Trap(IncreaseCounter, counter_ptr_); |
| 117 } | 120 } |
| 118 return Allow(); | 121 return Allow(); |
| 119 } | 122 } |
| 120 | 123 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 } | 210 } |
| 208 | 211 |
| 209 // A simple blacklist policy, with a SIGSYS handler | 212 // A simple blacklist policy, with a SIGSYS handler |
| 210 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { | 213 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { |
| 211 // We also check that the auxiliary data is correct | 214 // We also check that the auxiliary data is correct |
| 212 SANDBOX_ASSERT(aux); | 215 SANDBOX_ASSERT(aux); |
| 213 *(static_cast<int*>(aux)) = kExpectedReturnValue; | 216 *(static_cast<int*>(aux)) = kExpectedReturnValue; |
| 214 return -ENOMEM; | 217 return -ENOMEM; |
| 215 } | 218 } |
| 216 | 219 |
| 217 ErrorCode BlacklistNanosleepPolicySigsys(SandboxBPF* sandbox, | 220 class BlacklistNanosleepTrapPolicy : public SandboxBPFDSLPolicy { |
| 218 int sysno, | 221 public: |
| 219 int* aux) { | 222 explicit BlacklistNanosleepTrapPolicy(int* aux) : aux_(aux) {} |
| 220 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | 223 virtual ~BlacklistNanosleepTrapPolicy() {} |
| 221 switch (sysno) { | 224 |
| 222 case __NR_nanosleep: | 225 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { |
| 223 return sandbox->Trap(EnomemHandler, aux); | 226 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 224 default: | 227 switch (sysno) { |
| 225 return ErrorCode(ErrorCode::ERR_ALLOWED); | 228 case __NR_nanosleep: |
| 229 return Trap(EnomemHandler, aux_); |
| 230 default: |
| 231 return Allow(); |
| 232 } |
| 226 } | 233 } |
| 227 } | 234 |
| 235 private: |
| 236 int* aux_; |
| 237 |
| 238 DISALLOW_COPY_AND_ASSIGN(BlacklistNanosleepTrapPolicy); |
| 239 }; |
| 228 | 240 |
| 229 BPF_TEST(SandboxBPF, | 241 BPF_TEST(SandboxBPF, |
| 230 BasicBlacklistWithSigsys, | 242 BasicBlacklistWithSigsys, |
| 231 BlacklistNanosleepPolicySigsys, | 243 BlacklistNanosleepTrapPolicy, |
| 232 int /* (*BPF_AUX) */) { | 244 int /* (*BPF_AUX) */) { |
| 233 // getpid() should work properly | 245 // getpid() should work properly |
| 234 errno = 0; | 246 errno = 0; |
| 235 BPF_ASSERT(syscall(__NR_getpid) > 0); | 247 BPF_ASSERT(syscall(__NR_getpid) > 0); |
| 236 BPF_ASSERT(errno == 0); | 248 BPF_ASSERT(errno == 0); |
| 237 | 249 |
| 238 // Our Auxiliary Data, should be reset by the signal handler | 250 // Our Auxiliary Data, should be reset by the signal handler |
| 239 *BPF_AUX = -1; | 251 *BPF_AUX = -1; |
| 240 const struct timespec ts = {0, 0}; | 252 const struct timespec ts = {0, 0}; |
| 241 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 253 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 | 510 |
| 499 // Verify that within the callback function all filtering is temporarily | 511 // Verify that within the callback function all filtering is temporarily |
| 500 // disabled. | 512 // disabled. |
| 501 BPF_ASSERT(syscall(__NR_getpid) > 1); | 513 BPF_ASSERT(syscall(__NR_getpid) > 1); |
| 502 | 514 |
| 503 // Verify that we can now call the underlying system call without causing | 515 // Verify that we can now call the underlying system call without causing |
| 504 // infinite recursion. | 516 // infinite recursion. |
| 505 return SandboxBPF::ForwardSyscall(args); | 517 return SandboxBPF::ForwardSyscall(args); |
| 506 } | 518 } |
| 507 | 519 |
| 508 ErrorCode GreyListedPolicy(SandboxBPF* sandbox, int sysno, int* aux) { | 520 class GreyListedPolicy : public SandboxBPFDSLPolicy { |
| 509 // Set the global environment for unsafe traps once. | 521 public: |
| 510 if (sysno == MIN_SYSCALL) { | 522 explicit GreyListedPolicy(int* aux) : aux_(aux) { |
| 523 // Set the global environment for unsafe traps once. |
| 511 EnableUnsafeTraps(); | 524 EnableUnsafeTraps(); |
| 512 } | 525 } |
| 526 virtual ~GreyListedPolicy() {} |
| 513 | 527 |
| 514 // Some system calls must always be allowed, if our policy wants to make | 528 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { |
| 515 // use of UnsafeTrap() | 529 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 516 if (SandboxBPF::IsRequiredForUnsafeTrap(sysno)) { | 530 // Some system calls must always be allowed, if our policy wants to make |
| 517 return ErrorCode(ErrorCode::ERR_ALLOWED); | 531 // use of UnsafeTrap() |
| 518 } else if (sysno == __NR_getpid) { | 532 if (SandboxBPF::IsRequiredForUnsafeTrap(sysno)) { |
| 519 // Disallow getpid() | 533 return Allow(); |
| 520 return ErrorCode(EPERM); | 534 } else if (sysno == __NR_getpid) { |
| 521 } else if (SandboxBPF::IsValidSyscallNumber(sysno)) { | 535 // Disallow getpid() |
| 522 // Allow (and count) all other system calls. | 536 return Error(EPERM); |
| 523 return sandbox->UnsafeTrap(CountSyscalls, aux); | 537 } else { |
| 524 } else { | 538 // Allow (and count) all other system calls. |
| 525 return ErrorCode(ENOSYS); | 539 return UnsafeTrap(CountSyscalls, aux_); |
| 540 } |
| 526 } | 541 } |
| 527 } | 542 |
| 543 private: |
| 544 int* aux_; |
| 545 |
| 546 DISALLOW_COPY_AND_ASSIGN(GreyListedPolicy); |
| 547 }; |
| 528 | 548 |
| 529 BPF_TEST(SandboxBPF, GreyListedPolicy, GreyListedPolicy, int /* (*BPF_AUX) */) { | 549 BPF_TEST(SandboxBPF, GreyListedPolicy, GreyListedPolicy, int /* (*BPF_AUX) */) { |
| 530 BPF_ASSERT(syscall(__NR_getpid) == -1); | 550 BPF_ASSERT(syscall(__NR_getpid) == -1); |
| 531 BPF_ASSERT(errno == EPERM); | 551 BPF_ASSERT(errno == EPERM); |
| 532 BPF_ASSERT(*BPF_AUX == 0); | 552 BPF_ASSERT(*BPF_AUX == 0); |
| 533 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); | 553 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); |
| 534 BPF_ASSERT(*BPF_AUX == 2); | 554 BPF_ASSERT(*BPF_AUX == 2); |
| 535 char name[17] = {}; | 555 char name[17] = {}; |
| 536 BPF_ASSERT(!syscall(__NR_prctl, | 556 BPF_ASSERT(!syscall(__NR_prctl, |
| 537 PR_GET_NAME, | 557 PR_GET_NAME, |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 // the openat() system call. | 797 // the openat() system call. |
| 778 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); | 798 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); |
| 779 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), | 799 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), |
| 780 static_cast<int>(args.args[2])); | 800 static_cast<int>(args.args[2])); |
| 781 default: | 801 default: |
| 782 BPF_ASSERT(false); | 802 BPF_ASSERT(false); |
| 783 return -ENOSYS; | 803 return -ENOSYS; |
| 784 } | 804 } |
| 785 } | 805 } |
| 786 | 806 |
| 787 ErrorCode DenyOpenPolicy(SandboxBPF* sandbox, | 807 class DenyOpenPolicy : public SandboxBPFDSLPolicy { |
| 788 int sysno, | 808 public: |
| 789 InitializedOpenBroker* iob) { | 809 explicit DenyOpenPolicy(InitializedOpenBroker* iob) : iob_(iob) {} |
| 790 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 810 virtual ~DenyOpenPolicy() {} |
| 791 return ErrorCode(ENOSYS); | 811 |
| 812 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { |
| 813 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 814 |
| 815 switch (sysno) { |
| 816 case __NR_faccessat: |
| 817 #if defined(__NR_access) |
| 818 case __NR_access: |
| 819 #endif |
| 820 #if defined(__NR_open) |
| 821 case __NR_open: |
| 822 #endif |
| 823 case __NR_openat: |
| 824 // We get a InitializedOpenBroker class, but our trap handler wants |
| 825 // the BrokerProcess object. |
| 826 return Trap(BrokerOpenTrapHandler, iob_->broker_process()); |
| 827 default: |
| 828 return Allow(); |
| 829 } |
| 792 } | 830 } |
| 793 | 831 |
| 794 switch (sysno) { | 832 private: |
| 795 case __NR_faccessat: | 833 InitializedOpenBroker* iob_; |
| 796 #if defined(__NR_access) | 834 |
| 797 case __NR_access: | 835 DISALLOW_COPY_AND_ASSIGN(DenyOpenPolicy); |
| 798 #endif | 836 }; |
| 799 #if defined(__NR_open) | |
| 800 case __NR_open: | |
| 801 #endif | |
| 802 case __NR_openat: | |
| 803 // We get a InitializedOpenBroker class, but our trap handler wants | |
| 804 // the BrokerProcess object. | |
| 805 return ErrorCode( | |
| 806 sandbox->Trap(BrokerOpenTrapHandler, iob->broker_process())); | |
| 807 default: | |
| 808 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
| 809 } | |
| 810 } | |
| 811 | 837 |
| 812 // We use a InitializedOpenBroker class, so that we can run unsandboxed | 838 // We use a InitializedOpenBroker class, so that we can run unsandboxed |
| 813 // code in its constructor, which is the only way to do so in a BPF_TEST. | 839 // code in its constructor, which is the only way to do so in a BPF_TEST. |
| 814 BPF_TEST(SandboxBPF, | 840 BPF_TEST(SandboxBPF, |
| 815 UseOpenBroker, | 841 UseOpenBroker, |
| 816 DenyOpenPolicy, | 842 DenyOpenPolicy, |
| 817 InitializedOpenBroker /* (*BPF_AUX) */) { | 843 InitializedOpenBroker /* (*BPF_AUX) */) { |
| 818 BPF_ASSERT(BPF_AUX->initialized()); | 844 BPF_ASSERT(BPF_AUX->initialized()); |
| 819 BrokerProcess* broker_process = BPF_AUX->broker_process(); | 845 BrokerProcess* broker_process = BPF_AUX->broker_process(); |
| 820 BPF_ASSERT(broker_process != NULL); | 846 BPF_ASSERT(broker_process != NULL); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 } | 975 } |
| 950 | 976 |
| 951 ~EqualityStressTest() { | 977 ~EqualityStressTest() { |
| 952 for (std::vector<ArgValue*>::iterator iter = arg_values_.begin(); | 978 for (std::vector<ArgValue*>::iterator iter = arg_values_.begin(); |
| 953 iter != arg_values_.end(); | 979 iter != arg_values_.end(); |
| 954 ++iter) { | 980 ++iter) { |
| 955 DeleteArgValue(*iter); | 981 DeleteArgValue(*iter); |
| 956 } | 982 } |
| 957 } | 983 } |
| 958 | 984 |
| 959 ErrorCode Policy(SandboxBPF* sandbox, int sysno) { | 985 ResultExpr Policy(int sysno) { |
| 960 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 986 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
| 961 // FIXME: we should really not have to do that in a trivial policy | 987 if (sysno < 0 || sysno >= (int)arg_values_.size() || |
| 962 return ErrorCode(ENOSYS); | 988 IsReservedSyscall(sysno)) { |
| 963 } else if (sysno < 0 || sysno >= (int)arg_values_.size() || | |
| 964 IsReservedSyscall(sysno)) { | |
| 965 // We only return ErrorCode values for the system calls that | 989 // We only return ErrorCode values for the system calls that |
| 966 // are part of our test data. Every other system call remains | 990 // are part of our test data. Every other system call remains |
| 967 // allowed. | 991 // allowed. |
| 968 return ErrorCode(ErrorCode::ERR_ALLOWED); | 992 return Allow(); |
| 969 } else { | 993 } else { |
| 970 // ToErrorCode() turns an ArgValue object into an ErrorCode that is | 994 // ToErrorCode() turns an ArgValue object into an ErrorCode that is |
| 971 // suitable for use by a sandbox policy. | 995 // suitable for use by a sandbox policy. |
| 972 return ToErrorCode(sandbox, arg_values_[sysno]); | 996 return ToErrorCode(arg_values_[sysno]); |
| 973 } | 997 } |
| 974 } | 998 } |
| 975 | 999 |
| 976 void VerifyFilter() { | 1000 void VerifyFilter() { |
| 977 // Iterate over all system calls. Skip the system calls that have | 1001 // Iterate over all system calls. Skip the system calls that have |
| 978 // previously been determined as being reserved. | 1002 // previously been determined as being reserved. |
| 979 for (int sysno = 0; sysno < (int)arg_values_.size(); ++sysno) { | 1003 for (int sysno = 0; sysno < (int)arg_values_.size(); ++sysno) { |
| 980 if (!arg_values_[sysno]) { | 1004 if (!arg_values_[sysno]) { |
| 981 // Skip reserved system calls. | 1005 // Skip reserved system calls. |
| 982 continue; | 1006 continue; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 } | 1133 } |
| 1110 delete[] arg_value->tests; | 1134 delete[] arg_value->tests; |
| 1111 } | 1135 } |
| 1112 if (!arg_value->err) { | 1136 if (!arg_value->err) { |
| 1113 DeleteArgValue(arg_value->arg_value); | 1137 DeleteArgValue(arg_value->arg_value); |
| 1114 } | 1138 } |
| 1115 delete arg_value; | 1139 delete arg_value; |
| 1116 } | 1140 } |
| 1117 } | 1141 } |
| 1118 | 1142 |
| 1119 ErrorCode ToErrorCode(SandboxBPF* sandbox, ArgValue* arg_value) { | 1143 ResultExpr ToErrorCode(ArgValue* arg_value) { |
| 1120 // Compute the ErrorCode that should be returned, if none of our | 1144 // Compute the ResultExpr that should be returned, if none of our |
| 1121 // tests succeed (i.e. the system call parameter doesn't match any | 1145 // tests succeed (i.e. the system call parameter doesn't match any |
| 1122 // of the values in arg_value->tests[].k_value). | 1146 // of the values in arg_value->tests[].k_value). |
| 1123 ErrorCode err; | 1147 ResultExpr err; |
| 1124 if (arg_value->err) { | 1148 if (arg_value->err) { |
| 1125 // If this was a leaf node, return the errno value that we expect to | 1149 // If this was a leaf node, return the errno value that we expect to |
| 1126 // return from the BPF filter program. | 1150 // return from the BPF filter program. |
| 1127 err = ErrorCode(arg_value->err); | 1151 err = Error(arg_value->err); |
| 1128 } else { | 1152 } else { |
| 1129 // If this wasn't a leaf node yet, recursively descend into the rest | 1153 // If this wasn't a leaf node yet, recursively descend into the rest |
| 1130 // of the tree. This will end up adding a few more SandboxBPF::Cond() | 1154 // of the tree. This will end up adding a few more SandboxBPF::Cond() |
| 1131 // tests to our ErrorCode. | 1155 // tests to our ErrorCode. |
| 1132 err = ToErrorCode(sandbox, arg_value->arg_value); | 1156 err = ToErrorCode(arg_value->arg_value); |
| 1133 } | 1157 } |
| 1134 | 1158 |
| 1135 // Now, iterate over all the test cases that we want to compare against. | 1159 // Now, iterate over all the test cases that we want to compare against. |
| 1136 // This builds a chain of SandboxBPF::Cond() tests | 1160 // This builds a chain of SandboxBPF::Cond() tests |
| 1137 // (aka "if ... elif ... elif ... elif ... fi") | 1161 // (aka "if ... elif ... elif ... elif ... fi") |
| 1138 for (int n = arg_value->size; n-- > 0;) { | 1162 for (int n = arg_value->size; n-- > 0;) { |
| 1139 ErrorCode matched; | 1163 ResultExpr matched; |
| 1140 // Again, we distinguish between leaf nodes and subtrees. | 1164 // Again, we distinguish between leaf nodes and subtrees. |
| 1141 if (arg_value->tests[n].err) { | 1165 if (arg_value->tests[n].err) { |
| 1142 matched = ErrorCode(arg_value->tests[n].err); | 1166 matched = Error(arg_value->tests[n].err); |
| 1143 } else { | 1167 } else { |
| 1144 matched = ToErrorCode(sandbox, arg_value->tests[n].arg_value); | 1168 matched = ToErrorCode(arg_value->tests[n].arg_value); |
| 1145 } | 1169 } |
| 1146 // For now, all of our tests are limited to 32bit. | 1170 // For now, all of our tests are limited to 32bit. |
| 1147 // We have separate tests that check the behavior of 32bit vs. 64bit | 1171 // We have separate tests that check the behavior of 32bit vs. 64bit |
| 1148 // conditional expressions. | 1172 // conditional expressions. |
| 1149 err = sandbox->Cond(arg_value->argno, | 1173 const Arg<uint32_t> arg(arg_value->argno); |
| 1150 ErrorCode::TP_32BIT, | 1174 err = If(arg == arg_value->tests[n].k_value, matched).Else(err); |
| 1151 ErrorCode::OP_EQUAL, | |
| 1152 arg_value->tests[n].k_value, | |
| 1153 matched, | |
| 1154 err); | |
| 1155 } | 1175 } |
| 1156 return err; | 1176 return err; |
| 1157 } | 1177 } |
| 1158 | 1178 |
| 1159 void Verify(int sysno, intptr_t* args, const ArgValue& arg_value) { | 1179 void Verify(int sysno, intptr_t* args, const ArgValue& arg_value) { |
| 1160 uint32_t mismatched = 0; | 1180 uint32_t mismatched = 0; |
| 1161 // Iterate over all the k_values in arg_value.tests[] and verify that | 1181 // Iterate over all the k_values in arg_value.tests[] and verify that |
| 1162 // we see the expected return values from system calls, when we pass | 1182 // we see the expected return values from system calls, when we pass |
| 1163 // the k_value as a parameter in a system call. | 1183 // the k_value as a parameter in a system call. |
| 1164 for (int n = arg_value.size; n-- > 0;) { | 1184 for (int n = arg_value.size; n-- > 0;) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 // increased too much, the test will start failing. | 1234 // increased too much, the test will start failing. |
| 1215 #if defined(__aarch64__) | 1235 #if defined(__aarch64__) |
| 1216 static const int kNumTestCases = 30; | 1236 static const int kNumTestCases = 30; |
| 1217 #else | 1237 #else |
| 1218 static const int kNumTestCases = 40; | 1238 static const int kNumTestCases = 40; |
| 1219 #endif | 1239 #endif |
| 1220 static const int kMaxFanOut = 3; | 1240 static const int kMaxFanOut = 3; |
| 1221 static const int kMaxArgs = 6; | 1241 static const int kMaxArgs = 6; |
| 1222 }; | 1242 }; |
| 1223 | 1243 |
| 1224 ErrorCode EqualityStressTestPolicy(SandboxBPF* sandbox, | 1244 class EqualityStressTestPolicy : public SandboxBPFDSLPolicy { |
| 1225 int sysno, | 1245 public: |
| 1226 EqualityStressTest* aux) { | 1246 explicit EqualityStressTestPolicy(EqualityStressTest* aux) : aux_(aux) {} |
| 1227 DCHECK(aux); | 1247 virtual ~EqualityStressTestPolicy() {} |
| 1228 return aux->Policy(sandbox, sysno); | 1248 |
| 1229 } | 1249 virtual ResultExpr EvaluateSyscall(int sysno) const OVERRIDE { |
| 1250 return aux_->Policy(sysno); |
| 1251 } |
| 1252 |
| 1253 private: |
| 1254 EqualityStressTest* aux_; |
| 1255 |
| 1256 DISALLOW_COPY_AND_ASSIGN(EqualityStressTestPolicy); |
| 1257 }; |
| 1230 | 1258 |
| 1231 BPF_TEST(SandboxBPF, | 1259 BPF_TEST(SandboxBPF, |
| 1232 EqualityTests, | 1260 EqualityTests, |
| 1233 EqualityStressTestPolicy, | 1261 EqualityStressTestPolicy, |
| 1234 EqualityStressTest /* (*BPF_AUX) */) { | 1262 EqualityStressTest /* (*BPF_AUX) */) { |
| 1235 BPF_AUX->VerifyFilter(); | 1263 BPF_AUX->VerifyFilter(); |
| 1236 } | 1264 } |
| 1237 | 1265 |
| 1238 class EqualityArgumentWidthPolicy : public SandboxBPFDSLPolicy { | 1266 class EqualityArgumentWidthPolicy : public SandboxBPFDSLPolicy { |
| 1239 public: | 1267 public: |
| (...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2362 BPF_ASSERT_EQ(ENOSYS, errno); | 2390 BPF_ASSERT_EQ(ENOSYS, errno); |
| 2363 | 2391 |
| 2364 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); | 2392 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); |
| 2365 BPF_ASSERT_EQ(EPERM, errno); | 2393 BPF_ASSERT_EQ(EPERM, errno); |
| 2366 } | 2394 } |
| 2367 | 2395 |
| 2368 } // namespace | 2396 } // namespace |
| 2369 | 2397 |
| 2370 } // namespace bpf_dsl | 2398 } // namespace bpf_dsl |
| 2371 } // namespace sandbox | 2399 } // namespace sandbox |
| OLD | NEW |