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 |