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 <errno.h> | 5 #include <errno.h> |
6 #include <pthread.h> | 6 #include <pthread.h> |
7 #include <sched.h> | 7 #include <sched.h> |
8 #include <sys/prctl.h> | 8 #include <sys/prctl.h> |
9 #include <sys/syscall.h> | 9 #include <sys/syscall.h> |
10 #include <sys/time.h> | 10 #include <sys/time.h> |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "sandbox/linux/seccomp-bpf/syscall.h" | 26 #include "sandbox/linux/seccomp-bpf/syscall.h" |
27 #include "sandbox/linux/seccomp-bpf/trap.h" | 27 #include "sandbox/linux/seccomp-bpf/trap.h" |
28 #include "sandbox/linux/seccomp-bpf/verifier.h" | 28 #include "sandbox/linux/seccomp-bpf/verifier.h" |
29 #include "sandbox/linux/services/broker_process.h" | 29 #include "sandbox/linux/services/broker_process.h" |
30 #include "sandbox/linux/services/linux_syscalls.h" | 30 #include "sandbox/linux/services/linux_syscalls.h" |
31 #include "sandbox/linux/tests/unit_tests.h" | 31 #include "sandbox/linux/tests/unit_tests.h" |
32 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
33 | 33 |
34 // Workaround for Android's prctl.h file. | 34 // Workaround for Android's prctl.h file. |
35 #ifndef PR_GET_ENDIAN | 35 #ifndef PR_GET_ENDIAN |
36 #define PR_GET_ENDIAN 19 | 36 #define PR_GET_ENDIAN 19 |
37 #endif | 37 #endif |
38 #ifndef PR_CAPBSET_READ | 38 #ifndef PR_CAPBSET_READ |
39 #define PR_CAPBSET_READ 23 | 39 #define PR_CAPBSET_READ 23 |
40 #define PR_CAPBSET_DROP 24 | 40 #define PR_CAPBSET_DROP 24 |
41 #endif | 41 #endif |
42 | 42 |
43 using namespace playground2; | 43 using namespace playground2; |
44 using sandbox::BrokerProcess; | 44 using sandbox::BrokerProcess; |
45 | 45 |
46 namespace { | 46 namespace { |
47 | 47 |
48 const int kExpectedReturnValue = 42; | 48 const int kExpectedReturnValue = 42; |
49 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING"; | 49 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING"; |
50 | 50 |
51 // This test should execute no matter whether we have kernel support. So, | 51 // This test should execute no matter whether we have kernel support. So, |
52 // we make it a TEST() instead of a BPF_TEST(). | 52 // we make it a TEST() instead of a BPF_TEST(). |
53 TEST(SandboxBpf, CallSupports) { | 53 TEST(SandboxBpf, CallSupports) { |
54 // We check that we don't crash, but it's ok if the kernel doesn't | 54 // We check that we don't crash, but it's ok if the kernel doesn't |
55 // support it. | 55 // support it. |
56 bool seccomp_bpf_supported = | 56 bool seccomp_bpf_supported = |
57 Sandbox::SupportsSeccompSandbox(-1) == Sandbox::STATUS_AVAILABLE; | 57 Sandbox::SupportsSeccompSandbox(-1) == Sandbox::STATUS_AVAILABLE; |
58 // We want to log whether or not seccomp BPF is actually supported | 58 // We want to log whether or not seccomp BPF is actually supported |
59 // since actual test coverage depends on it. | 59 // since actual test coverage depends on it. |
60 RecordProperty("SeccompBPFSupported", | 60 RecordProperty("SeccompBPFSupported", |
61 seccomp_bpf_supported ? "true." : "false."); | 61 seccomp_bpf_supported ? "true." : "false."); |
62 std::cout << "Seccomp BPF supported: " | 62 std::cout << "Seccomp BPF supported: " |
63 << (seccomp_bpf_supported ? "true." : "false.") | 63 << (seccomp_bpf_supported ? "true." : "false.") << "\n"; |
64 << "\n"; | |
65 RecordProperty("PointerSize", sizeof(void*)); | 64 RecordProperty("PointerSize", sizeof(void*)); |
66 std::cout << "Pointer size: " << sizeof(void*) << "\n"; | 65 std::cout << "Pointer size: " << sizeof(void*) << "\n"; |
67 } | 66 } |
68 | 67 |
69 SANDBOX_TEST(SandboxBpf, CallSupportsTwice) { | 68 SANDBOX_TEST(SandboxBpf, CallSupportsTwice) { |
70 Sandbox::SupportsSeccompSandbox(-1); | 69 Sandbox::SupportsSeccompSandbox(-1); |
71 Sandbox::SupportsSeccompSandbox(-1); | 70 Sandbox::SupportsSeccompSandbox(-1); |
72 } | 71 } |
73 | 72 |
74 // BPF_TEST does a lot of the boiler-plate code around setting up a | 73 // BPF_TEST does a lot of the boiler-plate code around setting up a |
75 // policy and optional passing data between the caller, the policy and | 74 // policy and optional passing data between the caller, the policy and |
76 // any Trap() handlers. This is great for writing short and concise tests, | 75 // any Trap() handlers. This is great for writing short and concise tests, |
77 // and it helps us accidentally forgetting any of the crucial steps in | 76 // and it helps us accidentally forgetting any of the crucial steps in |
78 // setting up the sandbox. But it wouldn't hurt to have at least one test | 77 // setting up the sandbox. But it wouldn't hurt to have at least one test |
79 // that explicitly walks through all these steps. | 78 // that explicitly walks through all these steps. |
80 | 79 |
81 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void *aux) { | 80 intptr_t FakeGetPid(const struct arch_seccomp_data& args, void* aux) { |
82 BPF_ASSERT(aux); | 81 BPF_ASSERT(aux); |
83 pid_t *pid_ptr = static_cast<pid_t *>(aux); | 82 pid_t* pid_ptr = static_cast<pid_t*>(aux); |
84 return (*pid_ptr)++; | 83 return (*pid_ptr)++; |
85 } | 84 } |
86 | 85 |
87 ErrorCode VerboseAPITestingPolicy(Sandbox *sandbox, int sysno, void *aux) { | 86 ErrorCode VerboseAPITestingPolicy(Sandbox* sandbox, int sysno, void* aux) { |
88 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 87 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
89 return ErrorCode(ENOSYS); | 88 return ErrorCode(ENOSYS); |
90 } else if (sysno == __NR_getpid) { | 89 } else if (sysno == __NR_getpid) { |
91 return sandbox->Trap(FakeGetPid, aux); | 90 return sandbox->Trap(FakeGetPid, aux); |
92 } else { | 91 } else { |
93 return ErrorCode(ErrorCode::ERR_ALLOWED); | 92 return ErrorCode(ErrorCode::ERR_ALLOWED); |
94 } | 93 } |
95 } | 94 } |
96 | 95 |
97 SANDBOX_TEST(SandboxBpf, DISABLE_ON_TSAN(VerboseAPITesting)) { | 96 SANDBOX_TEST(SandboxBpf, DISABLE_ON_TSAN(VerboseAPITesting)) { |
(...skipping 11 matching lines...) Expand all Loading... |
109 BPF_ASSERT(test_var == 2); | 108 BPF_ASSERT(test_var == 2); |
110 | 109 |
111 // N.B.: Any future call to getpid() would corrupt the stack. | 110 // N.B.: Any future call to getpid() would corrupt the stack. |
112 // This is OK. The SANDBOX_TEST() macro is guaranteed to | 111 // This is OK. The SANDBOX_TEST() macro is guaranteed to |
113 // only ever call _exit() after the test completes. | 112 // only ever call _exit() after the test completes. |
114 } | 113 } |
115 } | 114 } |
116 | 115 |
117 // A simple blacklist test | 116 // A simple blacklist test |
118 | 117 |
119 ErrorCode BlacklistNanosleepPolicy(Sandbox *, int sysno, void *) { | 118 ErrorCode BlacklistNanosleepPolicy(Sandbox*, int sysno, void*) { |
120 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 119 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
121 // FIXME: we should really not have to do that in a trivial policy | 120 // FIXME: we should really not have to do that in a trivial policy |
122 return ErrorCode(ENOSYS); | 121 return ErrorCode(ENOSYS); |
123 } | 122 } |
124 | 123 |
125 switch (sysno) { | 124 switch (sysno) { |
126 case __NR_nanosleep: | 125 case __NR_nanosleep: |
127 return ErrorCode(EACCES); | 126 return ErrorCode(EACCES); |
128 default: | 127 default: |
129 return ErrorCode(ErrorCode::ERR_ALLOWED); | 128 return ErrorCode(ErrorCode::ERR_ALLOWED); |
130 } | 129 } |
131 } | 130 } |
132 | 131 |
133 BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | 132 BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { |
134 // nanosleep() should be denied | 133 // nanosleep() should be denied |
135 const struct timespec ts = {0, 0}; | 134 const struct timespec ts = {0, 0}; |
136 errno = 0; | 135 errno = 0; |
137 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 136 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
138 BPF_ASSERT(errno == EACCES); | 137 BPF_ASSERT(errno == EACCES); |
139 } | 138 } |
140 | 139 |
141 // Now do a simple whitelist test | 140 // Now do a simple whitelist test |
142 | 141 |
143 ErrorCode WhitelistGetpidPolicy(Sandbox *, int sysno, void *) { | 142 ErrorCode WhitelistGetpidPolicy(Sandbox*, int sysno, void*) { |
144 switch (sysno) { | 143 switch (sysno) { |
145 case __NR_getpid: | 144 case __NR_getpid: |
146 case __NR_exit_group: | 145 case __NR_exit_group: |
147 return ErrorCode(ErrorCode::ERR_ALLOWED); | 146 return ErrorCode(ErrorCode::ERR_ALLOWED); |
148 default: | 147 default: |
149 return ErrorCode(ENOMEM); | 148 return ErrorCode(ENOMEM); |
150 } | 149 } |
151 } | 150 } |
152 | 151 |
153 BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { | 152 BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { |
154 // getpid() should be allowed | 153 // getpid() should be allowed |
155 errno = 0; | 154 errno = 0; |
156 BPF_ASSERT(syscall(__NR_getpid) > 0); | 155 BPF_ASSERT(syscall(__NR_getpid) > 0); |
157 BPF_ASSERT(errno == 0); | 156 BPF_ASSERT(errno == 0); |
158 | 157 |
159 // getpgid() should be denied | 158 // getpgid() should be denied |
160 BPF_ASSERT(getpgid(0) == -1); | 159 BPF_ASSERT(getpgid(0) == -1); |
161 BPF_ASSERT(errno == ENOMEM); | 160 BPF_ASSERT(errno == ENOMEM); |
162 } | 161 } |
163 | 162 |
164 // A simple blacklist policy, with a SIGSYS handler | 163 // A simple blacklist policy, with a SIGSYS handler |
165 | 164 |
166 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) { | 165 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { |
167 // We also check that the auxiliary data is correct | 166 // We also check that the auxiliary data is correct |
168 SANDBOX_ASSERT(aux); | 167 SANDBOX_ASSERT(aux); |
169 *(static_cast<int*>(aux)) = kExpectedReturnValue; | 168 *(static_cast<int*>(aux)) = kExpectedReturnValue; |
170 return -ENOMEM; | 169 return -ENOMEM; |
171 } | 170 } |
172 | 171 |
173 ErrorCode BlacklistNanosleepPolicySigsys(Sandbox *sandbox, int sysno, | 172 ErrorCode BlacklistNanosleepPolicySigsys(Sandbox* sandbox, |
174 void *aux) { | 173 int sysno, |
| 174 void* aux) { |
175 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 175 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
176 // FIXME: we should really not have to do that in a trivial policy | 176 // FIXME: we should really not have to do that in a trivial policy |
177 return ErrorCode(ENOSYS); | 177 return ErrorCode(ENOSYS); |
178 } | 178 } |
179 | 179 |
180 switch (sysno) { | 180 switch (sysno) { |
181 case __NR_nanosleep: | 181 case __NR_nanosleep: |
182 return sandbox->Trap(EnomemHandler, aux); | 182 return sandbox->Trap(EnomemHandler, aux); |
183 default: | 183 default: |
184 return ErrorCode(ErrorCode::ERR_ALLOWED); | 184 return ErrorCode(ErrorCode::ERR_ALLOWED); |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 BPF_TEST(SandboxBpf, BasicBlacklistWithSigsys, | 188 BPF_TEST(SandboxBpf, |
189 BlacklistNanosleepPolicySigsys, int /* BPF_AUX */) { | 189 BasicBlacklistWithSigsys, |
| 190 BlacklistNanosleepPolicySigsys, |
| 191 int /* BPF_AUX */) { |
190 // getpid() should work properly | 192 // getpid() should work properly |
191 errno = 0; | 193 errno = 0; |
192 BPF_ASSERT(syscall(__NR_getpid) > 0); | 194 BPF_ASSERT(syscall(__NR_getpid) > 0); |
193 BPF_ASSERT(errno == 0); | 195 BPF_ASSERT(errno == 0); |
194 | 196 |
195 // Our Auxiliary Data, should be reset by the signal handler | 197 // Our Auxiliary Data, should be reset by the signal handler |
196 BPF_AUX = -1; | 198 BPF_AUX = -1; |
197 const struct timespec ts = {0, 0}; | 199 const struct timespec ts = {0, 0}; |
198 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 200 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
199 BPF_ASSERT(errno == ENOMEM); | 201 BPF_ASSERT(errno == ENOMEM); |
200 | 202 |
201 // We expect the signal handler to modify AuxData | 203 // We expect the signal handler to modify AuxData |
202 BPF_ASSERT(BPF_AUX == kExpectedReturnValue); | 204 BPF_ASSERT(BPF_AUX == kExpectedReturnValue); |
203 } | 205 } |
204 | 206 |
205 // A simple test that verifies we can return arbitrary errno values. | 207 // A simple test that verifies we can return arbitrary errno values. |
206 | 208 |
207 ErrorCode ErrnoTestPolicy(Sandbox *, int sysno, void *) { | 209 ErrorCode ErrnoTestPolicy(Sandbox*, int sysno, void*) { |
208 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 210 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
209 // FIXME: we should really not have to do that in a trivial policy | 211 // FIXME: we should really not have to do that in a trivial policy |
210 return ErrorCode(ENOSYS); | 212 return ErrorCode(ENOSYS); |
211 } | 213 } |
212 | 214 |
213 switch (sysno) { | 215 switch (sysno) { |
214 case __NR_dup2: | 216 case __NR_dup2: |
215 // Pretend that dup2() worked, but don't actually do anything. | 217 // Pretend that dup2() worked, but don't actually do anything. |
216 return ErrorCode(0); | 218 return ErrorCode(0); |
217 case __NR_setuid: | 219 case __NR_setuid: |
218 #if defined(__NR_setuid32) | 220 #if defined(__NR_setuid32) |
219 case __NR_setuid32: | 221 case __NR_setuid32: |
220 #endif | 222 #endif |
221 // Return errno = 1. | 223 // Return errno = 1. |
222 return ErrorCode(1); | 224 return ErrorCode(1); |
223 case __NR_setgid: | 225 case __NR_setgid: |
224 #if defined(__NR_setgid32) | 226 #if defined(__NR_setgid32) |
225 case __NR_setgid32: | 227 case __NR_setgid32: |
226 #endif | 228 #endif |
227 // Return maximum errno value (typically 4095). | 229 // Return maximum errno value (typically 4095). |
228 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); | 230 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); |
229 case __NR_uname: | 231 case __NR_uname: |
230 // Return errno = 42; | 232 // Return errno = 42; |
231 return ErrorCode(42); | 233 return ErrorCode(42); |
232 default: | 234 default: |
233 return ErrorCode(ErrorCode::ERR_ALLOWED); | 235 return ErrorCode(ErrorCode::ERR_ALLOWED); |
234 } | 236 } |
235 } | 237 } |
236 | 238 |
237 BPF_TEST(SandboxBpf, ErrnoTest, ErrnoTestPolicy) { | 239 BPF_TEST(SandboxBpf, ErrnoTest, ErrnoTestPolicy) { |
238 // Verify that dup2() returns success, but doesn't actually run. | 240 // Verify that dup2() returns success, but doesn't actually run. |
239 int fds[4]; | 241 int fds[4]; |
240 BPF_ASSERT(pipe(fds) == 0); | 242 BPF_ASSERT(pipe(fds) == 0); |
241 BPF_ASSERT(pipe(fds+2) == 0); | 243 BPF_ASSERT(pipe(fds + 2) == 0); |
242 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); | 244 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); |
243 char buf[1] = { }; | 245 char buf[1] = {}; |
244 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); | 246 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); |
245 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); | 247 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); |
246 BPF_ASSERT(read(fds[0], buf, 1) == 1); | 248 BPF_ASSERT(read(fds[0], buf, 1) == 1); |
247 | 249 |
248 // If dup2() executed, we will read \xAA, but it dup2() has been turned | 250 // If dup2() executed, we will read \xAA, but it dup2() has been turned |
249 // into a no-op by our policy, then we will read \x55. | 251 // into a no-op by our policy, then we will read \x55. |
250 BPF_ASSERT(buf[0] == '\x55'); | 252 BPF_ASSERT(buf[0] == '\x55'); |
251 | 253 |
252 // Verify that we can return the minimum and maximum errno values. | 254 // Verify that we can return the minimum and maximum errno values. |
253 errno = 0; | 255 errno = 0; |
(...skipping 15 matching lines...) Expand all Loading... |
269 | 271 |
270 // Finally, test an errno in between the minimum and maximum. | 272 // Finally, test an errno in between the minimum and maximum. |
271 errno = 0; | 273 errno = 0; |
272 struct utsname uts_buf; | 274 struct utsname uts_buf; |
273 BPF_ASSERT(uname(&uts_buf) == -1); | 275 BPF_ASSERT(uname(&uts_buf) == -1); |
274 BPF_ASSERT(errno == 42); | 276 BPF_ASSERT(errno == 42); |
275 } | 277 } |
276 | 278 |
277 // Testing the stacking of two sandboxes | 279 // Testing the stacking of two sandboxes |
278 | 280 |
279 ErrorCode StackingPolicyPartOne(Sandbox *sandbox, int sysno, void *) { | 281 ErrorCode StackingPolicyPartOne(Sandbox* sandbox, int sysno, void*) { |
280 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 282 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
281 return ErrorCode(ENOSYS); | 283 return ErrorCode(ENOSYS); |
282 } | 284 } |
283 | 285 |
284 switch (sysno) { | 286 switch (sysno) { |
285 case __NR_getppid: | 287 case __NR_getppid: |
286 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 288 return sandbox->Cond(0, |
| 289 ErrorCode::TP_32BIT, |
| 290 ErrorCode::OP_EQUAL, |
| 291 0, |
287 ErrorCode(ErrorCode::ERR_ALLOWED), | 292 ErrorCode(ErrorCode::ERR_ALLOWED), |
288 ErrorCode(EPERM)); | 293 ErrorCode(EPERM)); |
289 default: | 294 default: |
290 return ErrorCode(ErrorCode::ERR_ALLOWED); | 295 return ErrorCode(ErrorCode::ERR_ALLOWED); |
291 } | 296 } |
292 } | 297 } |
293 | 298 |
294 ErrorCode StackingPolicyPartTwo(Sandbox *sandbox, int sysno, void *) { | 299 ErrorCode StackingPolicyPartTwo(Sandbox* sandbox, int sysno, void*) { |
295 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 300 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
296 return ErrorCode(ENOSYS); | 301 return ErrorCode(ENOSYS); |
297 } | 302 } |
298 | 303 |
299 switch (sysno) { | 304 switch (sysno) { |
300 case __NR_getppid: | 305 case __NR_getppid: |
301 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 306 return sandbox->Cond(0, |
| 307 ErrorCode::TP_32BIT, |
| 308 ErrorCode::OP_EQUAL, |
| 309 0, |
302 ErrorCode(EINVAL), | 310 ErrorCode(EINVAL), |
303 ErrorCode(ErrorCode::ERR_ALLOWED)); | 311 ErrorCode(ErrorCode::ERR_ALLOWED)); |
304 default: | 312 default: |
305 return ErrorCode(ErrorCode::ERR_ALLOWED); | 313 return ErrorCode(ErrorCode::ERR_ALLOWED); |
306 } | 314 } |
307 } | 315 } |
308 | 316 |
309 BPF_TEST(SandboxBpf, StackingPolicy, StackingPolicyPartOne) { | 317 BPF_TEST(SandboxBpf, StackingPolicy, StackingPolicyPartOne) { |
310 errno = 0; | 318 errno = 0; |
311 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); | 319 BPF_ASSERT(syscall(__NR_getppid, 0) > 0); |
(...skipping 24 matching lines...) Expand all Loading... |
336 // We try to make sure we exercise optimizations in the BPF compiler. We make | 344 // We try to make sure we exercise optimizations in the BPF compiler. We make |
337 // sure that the compiler can have an opportunity to coalesce syscalls with | 345 // sure that the compiler can have an opportunity to coalesce syscalls with |
338 // contiguous numbers and we also make sure that disjoint sets can return the | 346 // contiguous numbers and we also make sure that disjoint sets can return the |
339 // same errno. | 347 // same errno. |
340 int SysnoToRandomErrno(int sysno) { | 348 int SysnoToRandomErrno(int sysno) { |
341 // Small contiguous sets of 3 system calls return an errno equal to the | 349 // Small contiguous sets of 3 system calls return an errno equal to the |
342 // index of that set + 1 (so that we never return a NUL errno). | 350 // index of that set + 1 (so that we never return a NUL errno). |
343 return ((sysno & ~3) >> 2) % 29 + 1; | 351 return ((sysno & ~3) >> 2) % 29 + 1; |
344 } | 352 } |
345 | 353 |
346 ErrorCode SyntheticPolicy(Sandbox *, int sysno, void *) { | 354 ErrorCode SyntheticPolicy(Sandbox*, int sysno, void*) { |
347 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 355 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
348 // FIXME: we should really not have to do that in a trivial policy | 356 // FIXME: we should really not have to do that in a trivial policy |
349 return ErrorCode(ENOSYS); | 357 return ErrorCode(ENOSYS); |
350 } | 358 } |
351 | 359 |
352 // TODO(jorgelo): remove this once the new code generator lands. | 360 // TODO(jorgelo): remove this once the new code generator lands. |
353 #if defined(__arm__) | 361 #if defined(__arm__) |
354 if (sysno > static_cast<int>(MAX_PUBLIC_SYSCALL)) { | 362 if (sysno > static_cast<int>(MAX_PUBLIC_SYSCALL)) { |
355 return ErrorCode(ENOSYS); | 363 return ErrorCode(ENOSYS); |
356 } | 364 } |
357 #endif | 365 #endif |
358 | 366 |
359 if (sysno == __NR_exit_group || sysno == __NR_write) { | 367 if (sysno == __NR_exit_group || sysno == __NR_write) { |
360 // exit_group() is special, we really need it to work. | 368 // exit_group() is special, we really need it to work. |
361 // write() is needed for BPF_ASSERT() to report a useful error message. | 369 // write() is needed for BPF_ASSERT() to report a useful error message. |
362 return ErrorCode(ErrorCode::ERR_ALLOWED); | 370 return ErrorCode(ErrorCode::ERR_ALLOWED); |
363 } else { | 371 } else { |
364 return ErrorCode(SysnoToRandomErrno(sysno)); | 372 return ErrorCode(SysnoToRandomErrno(sysno)); |
365 } | 373 } |
366 } | 374 } |
367 | 375 |
368 BPF_TEST(SandboxBpf, SyntheticPolicy, SyntheticPolicy) { | 376 BPF_TEST(SandboxBpf, SyntheticPolicy, SyntheticPolicy) { |
369 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int | 377 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int |
370 // overflow. | 378 // overflow. |
371 BPF_ASSERT( | 379 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= |
372 std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= | 380 static_cast<int>(MAX_PUBLIC_SYSCALL)); |
373 static_cast<int>(MAX_PUBLIC_SYSCALL)); | |
374 | 381 |
375 for (int syscall_number = static_cast<int>(MIN_SYSCALL); | 382 for (int syscall_number = static_cast<int>(MIN_SYSCALL); |
376 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); | 383 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); |
377 ++syscall_number) { | 384 ++syscall_number) { |
378 if (syscall_number == __NR_exit_group || | 385 if (syscall_number == __NR_exit_group || syscall_number == __NR_write) { |
379 syscall_number == __NR_write) { | |
380 // exit_group() is special | 386 // exit_group() is special |
381 continue; | 387 continue; |
382 } | 388 } |
383 errno = 0; | 389 errno = 0; |
384 BPF_ASSERT(syscall(syscall_number) == -1); | 390 BPF_ASSERT(syscall(syscall_number) == -1); |
385 BPF_ASSERT(errno == SysnoToRandomErrno(syscall_number)); | 391 BPF_ASSERT(errno == SysnoToRandomErrno(syscall_number)); |
386 } | 392 } |
387 } | 393 } |
388 | 394 |
389 #if defined(__arm__) | 395 #if defined(__arm__) |
390 // A simple policy that tests whether ARM private system calls are supported | 396 // A simple policy that tests whether ARM private system calls are supported |
391 // by our BPF compiler and by the BPF interpreter in the kernel. | 397 // by our BPF compiler and by the BPF interpreter in the kernel. |
392 | 398 |
393 // For ARM private system calls, return an errno equal to their offset from | 399 // For ARM private system calls, return an errno equal to their offset from |
394 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). | 400 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). |
395 int ArmPrivateSysnoToErrno(int sysno) { | 401 int ArmPrivateSysnoToErrno(int sysno) { |
396 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && | 402 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && |
397 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 403 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
398 return (sysno - MIN_PRIVATE_SYSCALL) + 1; | 404 return (sysno - MIN_PRIVATE_SYSCALL) + 1; |
399 } else { | 405 } else { |
400 return ENOSYS; | 406 return ENOSYS; |
401 } | 407 } |
402 } | 408 } |
403 | 409 |
404 ErrorCode ArmPrivatePolicy(Sandbox *, int sysno, void *) { | 410 ErrorCode ArmPrivatePolicy(Sandbox*, int sysno, void*) { |
405 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 411 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
406 // FIXME: we should really not have to do that in a trivial policy. | 412 // FIXME: we should really not have to do that in a trivial policy. |
407 return ErrorCode(ENOSYS); | 413 return ErrorCode(ENOSYS); |
408 } | 414 } |
409 | 415 |
410 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual | 416 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual |
411 // ARM private system calls. | 417 // ARM private system calls. |
412 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && | 418 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && |
413 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 419 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
414 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); | 420 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); |
415 } else { | 421 } else { |
416 return ErrorCode(ErrorCode::ERR_ALLOWED); | 422 return ErrorCode(ErrorCode::ERR_ALLOWED); |
417 } | 423 } |
418 } | 424 } |
419 | 425 |
420 BPF_TEST(SandboxBpf, ArmPrivatePolicy, ArmPrivatePolicy) { | 426 BPF_TEST(SandboxBpf, ArmPrivatePolicy, ArmPrivatePolicy) { |
421 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); | 427 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); |
422 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); | 428 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); |
423 ++syscall_number) { | 429 ++syscall_number) { |
424 errno = 0; | 430 errno = 0; |
425 BPF_ASSERT(syscall(syscall_number) == -1); | 431 BPF_ASSERT(syscall(syscall_number) == -1); |
426 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); | 432 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); |
427 } | 433 } |
428 } | 434 } |
429 #endif // defined(__arm__) | 435 #endif // defined(__arm__) |
430 | 436 |
431 intptr_t CountSyscalls(const struct arch_seccomp_data& args, void *aux) { | 437 intptr_t CountSyscalls(const struct arch_seccomp_data& args, void* aux) { |
432 // Count all invocations of our callback function. | 438 // Count all invocations of our callback function. |
433 ++*reinterpret_cast<int *>(aux); | 439 ++*reinterpret_cast<int*>(aux); |
434 | 440 |
435 // Verify that within the callback function all filtering is temporarily | 441 // Verify that within the callback function all filtering is temporarily |
436 // disabled. | 442 // disabled. |
437 BPF_ASSERT(syscall(__NR_getpid) > 1); | 443 BPF_ASSERT(syscall(__NR_getpid) > 1); |
438 | 444 |
439 // Verify that we can now call the underlying system call without causing | 445 // Verify that we can now call the underlying system call without causing |
440 // infinite recursion. | 446 // infinite recursion. |
441 return Sandbox::ForwardSyscall(args); | 447 return Sandbox::ForwardSyscall(args); |
442 } | 448 } |
443 | 449 |
444 ErrorCode GreyListedPolicy(Sandbox *sandbox, int sysno, void *aux) { | 450 ErrorCode GreyListedPolicy(Sandbox* sandbox, int sysno, void* aux) { |
445 // The use of UnsafeTrap() causes us to print a warning message. This is | 451 // The use of UnsafeTrap() causes us to print a warning message. This is |
446 // generally desirable, but it results in the unittest failing, as it doesn't | 452 // generally desirable, but it results in the unittest failing, as it doesn't |
447 // expect any messages on "stderr". So, temporarily disable messages. The | 453 // expect any messages on "stderr". So, temporarily disable messages. The |
448 // BPF_TEST() is guaranteed to turn messages back on, after the policy | 454 // BPF_TEST() is guaranteed to turn messages back on, after the policy |
449 // function has completed. | 455 // function has completed. |
450 setenv(kSandboxDebuggingEnv, "t", 0); | 456 setenv(kSandboxDebuggingEnv, "t", 0); |
451 Die::SuppressInfoMessages(true); | 457 Die::SuppressInfoMessages(true); |
452 | 458 |
453 // Some system calls must always be allowed, if our policy wants to make | 459 // Some system calls must always be allowed, if our policy wants to make |
454 // use of UnsafeTrap() | 460 // use of UnsafeTrap() |
455 if (sysno == __NR_rt_sigprocmask || | 461 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn |
456 sysno == __NR_rt_sigreturn | |
457 #if defined(__NR_sigprocmask) | 462 #if defined(__NR_sigprocmask) |
458 || sysno == __NR_sigprocmask | 463 || |
| 464 sysno == __NR_sigprocmask |
459 #endif | 465 #endif |
460 #if defined(__NR_sigreturn) | 466 #if defined(__NR_sigreturn) |
461 || sysno == __NR_sigreturn | 467 || |
| 468 sysno == __NR_sigreturn |
462 #endif | 469 #endif |
463 ) { | 470 ) { |
464 return ErrorCode(ErrorCode::ERR_ALLOWED); | 471 return ErrorCode(ErrorCode::ERR_ALLOWED); |
465 } else if (sysno == __NR_getpid) { | 472 } else if (sysno == __NR_getpid) { |
466 // Disallow getpid() | 473 // Disallow getpid() |
467 return ErrorCode(EPERM); | 474 return ErrorCode(EPERM); |
468 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 475 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
469 // Allow (and count) all other system calls. | 476 // Allow (and count) all other system calls. |
470 return sandbox->UnsafeTrap(CountSyscalls, aux); | 477 return sandbox->UnsafeTrap(CountSyscalls, aux); |
471 } else { | 478 } else { |
472 return ErrorCode(ENOSYS); | 479 return ErrorCode(ENOSYS); |
473 } | 480 } |
474 } | 481 } |
475 | 482 |
476 BPF_TEST(SandboxBpf, GreyListedPolicy, | 483 BPF_TEST(SandboxBpf, GreyListedPolicy, GreyListedPolicy, int /* BPF_AUX */) { |
477 GreyListedPolicy, int /* BPF_AUX */) { | |
478 BPF_ASSERT(syscall(__NR_getpid) == -1); | 484 BPF_ASSERT(syscall(__NR_getpid) == -1); |
479 BPF_ASSERT(errno == EPERM); | 485 BPF_ASSERT(errno == EPERM); |
480 BPF_ASSERT(BPF_AUX == 0); | 486 BPF_ASSERT(BPF_AUX == 0); |
481 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); | 487 BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid)); |
482 BPF_ASSERT(BPF_AUX == 2); | 488 BPF_ASSERT(BPF_AUX == 2); |
483 char name[17] = { }; | 489 char name[17] = {}; |
484 BPF_ASSERT(!syscall(__NR_prctl, PR_GET_NAME, name, (void *)NULL, | 490 BPF_ASSERT(!syscall(__NR_prctl, |
485 (void *)NULL, (void *)NULL)); | 491 PR_GET_NAME, |
| 492 name, |
| 493 (void*)NULL, |
| 494 (void*)NULL, |
| 495 (void*)NULL)); |
486 BPF_ASSERT(BPF_AUX == 3); | 496 BPF_ASSERT(BPF_AUX == 3); |
487 BPF_ASSERT(*name); | 497 BPF_ASSERT(*name); |
488 } | 498 } |
489 | 499 |
490 SANDBOX_TEST(SandboxBpf, EnableUnsafeTrapsInSigSysHandler) { | 500 SANDBOX_TEST(SandboxBpf, EnableUnsafeTrapsInSigSysHandler) { |
491 // Disabling warning messages that could confuse our test framework. | 501 // Disabling warning messages that could confuse our test framework. |
492 setenv(kSandboxDebuggingEnv, "t", 0); | 502 setenv(kSandboxDebuggingEnv, "t", 0); |
493 Die::SuppressInfoMessages(true); | 503 Die::SuppressInfoMessages(true); |
494 | 504 |
495 unsetenv(kSandboxDebuggingEnv); | 505 unsetenv(kSandboxDebuggingEnv); |
496 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); | 506 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); |
497 setenv(kSandboxDebuggingEnv, "", 1); | 507 setenv(kSandboxDebuggingEnv, "", 1); |
498 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); | 508 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == false); |
499 setenv(kSandboxDebuggingEnv, "t", 1); | 509 setenv(kSandboxDebuggingEnv, "t", 1); |
500 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == true); | 510 SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == true); |
501 } | 511 } |
502 | 512 |
503 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void *) { | 513 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { |
504 if (args.args[0] == PR_CAPBSET_DROP && | 514 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { |
505 static_cast<int>(args.args[1]) == -1) { | |
506 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always | 515 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always |
507 // return an error. But our handler allows this call. | 516 // return an error. But our handler allows this call. |
508 return 0; | 517 return 0; |
509 } else { | 518 } else { |
510 return Sandbox::ForwardSyscall(args); | 519 return Sandbox::ForwardSyscall(args); |
511 } | 520 } |
512 } | 521 } |
513 | 522 |
514 ErrorCode PrctlPolicy(Sandbox *sandbox, int sysno, void *aux) { | 523 ErrorCode PrctlPolicy(Sandbox* sandbox, int sysno, void* aux) { |
515 setenv(kSandboxDebuggingEnv, "t", 0); | 524 setenv(kSandboxDebuggingEnv, "t", 0); |
516 Die::SuppressInfoMessages(true); | 525 Die::SuppressInfoMessages(true); |
517 | 526 |
518 if (sysno == __NR_prctl) { | 527 if (sysno == __NR_prctl) { |
519 // Handle prctl() inside an UnsafeTrap() | 528 // Handle prctl() inside an UnsafeTrap() |
520 return sandbox->UnsafeTrap(PrctlHandler, NULL); | 529 return sandbox->UnsafeTrap(PrctlHandler, NULL); |
521 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 530 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
522 // Allow all other system calls. | 531 // Allow all other system calls. |
523 return ErrorCode(ErrorCode::ERR_ALLOWED); | 532 return ErrorCode(ErrorCode::ERR_ALLOWED); |
524 } else { | 533 } else { |
525 return ErrorCode(ENOSYS); | 534 return ErrorCode(ENOSYS); |
526 } | 535 } |
527 } | 536 } |
528 | 537 |
529 BPF_TEST(SandboxBpf, ForwardSyscall, PrctlPolicy) { | 538 BPF_TEST(SandboxBpf, ForwardSyscall, PrctlPolicy) { |
530 // This call should never be allowed. But our policy will intercept it and | 539 // This call should never be allowed. But our policy will intercept it and |
531 // let it pass successfully. | 540 // let it pass successfully. |
532 BPF_ASSERT(!prctl(PR_CAPBSET_DROP, -1, (void *)NULL, (void *)NULL, | 541 BPF_ASSERT( |
533 (void *)NULL)); | 542 !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL)); |
534 | 543 |
535 // Verify that the call will fail, if it makes it all the way to the kernel. | 544 // Verify that the call will fail, if it makes it all the way to the kernel. |
536 BPF_ASSERT(prctl(PR_CAPBSET_DROP, -2, (void *)NULL, (void *)NULL, | 545 BPF_ASSERT( |
537 (void *)NULL) == -1); | 546 prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1); |
538 | 547 |
539 // And verify that other uses of prctl() work just fine. | 548 // And verify that other uses of prctl() work just fine. |
540 char name[17] = { }; | 549 char name[17] = {}; |
541 BPF_ASSERT(!syscall(__NR_prctl, PR_GET_NAME, name, (void *)NULL, | 550 BPF_ASSERT(!syscall(__NR_prctl, |
542 (void *)NULL, (void *)NULL)); | 551 PR_GET_NAME, |
| 552 name, |
| 553 (void*)NULL, |
| 554 (void*)NULL, |
| 555 (void*)NULL)); |
543 BPF_ASSERT(*name); | 556 BPF_ASSERT(*name); |
544 | 557 |
545 // Finally, verify that system calls other than prctl() are completely | 558 // Finally, verify that system calls other than prctl() are completely |
546 // unaffected by our policy. | 559 // unaffected by our policy. |
547 struct utsname uts = { }; | 560 struct utsname uts = {}; |
548 BPF_ASSERT(!uname(&uts)); | 561 BPF_ASSERT(!uname(&uts)); |
549 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); | 562 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); |
550 } | 563 } |
551 | 564 |
552 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void *) { | 565 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { |
553 return Sandbox::ForwardSyscall(args); | 566 return Sandbox::ForwardSyscall(args); |
554 } | 567 } |
555 | 568 |
556 ErrorCode RedirectAllSyscallsPolicy(Sandbox *sandbox, int sysno, void *aux) { | 569 ErrorCode RedirectAllSyscallsPolicy(Sandbox* sandbox, int sysno, void* aux) { |
557 setenv(kSandboxDebuggingEnv, "t", 0); | 570 setenv(kSandboxDebuggingEnv, "t", 0); |
558 Die::SuppressInfoMessages(true); | 571 Die::SuppressInfoMessages(true); |
559 | 572 |
560 // Some system calls must always be allowed, if our policy wants to make | 573 // Some system calls must always be allowed, if our policy wants to make |
561 // use of UnsafeTrap() | 574 // use of UnsafeTrap() |
562 if (sysno == __NR_rt_sigprocmask || | 575 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn |
563 sysno == __NR_rt_sigreturn | |
564 #if defined(__NR_sigprocmask) | 576 #if defined(__NR_sigprocmask) |
565 || sysno == __NR_sigprocmask | 577 || |
| 578 sysno == __NR_sigprocmask |
566 #endif | 579 #endif |
567 #if defined(__NR_sigreturn) | 580 #if defined(__NR_sigreturn) |
568 || sysno == __NR_sigreturn | 581 || |
| 582 sysno == __NR_sigreturn |
569 #endif | 583 #endif |
570 ) { | 584 ) { |
571 return ErrorCode(ErrorCode::ERR_ALLOWED); | 585 return ErrorCode(ErrorCode::ERR_ALLOWED); |
572 } else if (Sandbox::IsValidSyscallNumber(sysno)) { | 586 } else if (Sandbox::IsValidSyscallNumber(sysno)) { |
573 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux); | 587 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux); |
574 } else { | 588 } else { |
575 return ErrorCode(ENOSYS); | 589 return ErrorCode(ENOSYS); |
576 } | 590 } |
577 } | 591 } |
578 | 592 |
579 int bus_handler_fd_ = -1; | 593 int bus_handler_fd_ = -1; |
580 | 594 |
581 void SigBusHandler(int, siginfo_t *info, void *void_context) { | 595 void SigBusHandler(int, siginfo_t* info, void* void_context) { |
582 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); | 596 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); |
583 } | 597 } |
584 | 598 |
585 BPF_TEST(SandboxBpf, SigBus, RedirectAllSyscallsPolicy) { | 599 BPF_TEST(SandboxBpf, SigBus, RedirectAllSyscallsPolicy) { |
586 // We use the SIGBUS bit in the signal mask as a thread-local boolean | 600 // We use the SIGBUS bit in the signal mask as a thread-local boolean |
587 // value in the implementation of UnsafeTrap(). This is obviously a bit | 601 // value in the implementation of UnsafeTrap(). This is obviously a bit |
588 // of a hack that could conceivably interfere with code that uses SIGBUS | 602 // of a hack that could conceivably interfere with code that uses SIGBUS |
589 // in more traditional ways. This test verifies that basic functionality | 603 // in more traditional ways. This test verifies that basic functionality |
590 // of SIGBUS is not impacted, but it is certainly possibly to construe | 604 // of SIGBUS is not impacted, but it is certainly possibly to construe |
591 // more complex uses of signals where our use of the SIGBUS mask is not | 605 // more complex uses of signals where our use of the SIGBUS mask is not |
592 // 100% transparent. This is expected behavior. | 606 // 100% transparent. This is expected behavior. |
593 int fds[2]; | 607 int fds[2]; |
594 BPF_ASSERT(pipe(fds) == 0); | 608 BPF_ASSERT(pipe(fds) == 0); |
595 bus_handler_fd_ = fds[1]; | 609 bus_handler_fd_ = fds[1]; |
596 struct sigaction sa = { }; | 610 struct sigaction sa = {}; |
597 sa.sa_sigaction = SigBusHandler; | 611 sa.sa_sigaction = SigBusHandler; |
598 sa.sa_flags = SA_SIGINFO; | 612 sa.sa_flags = SA_SIGINFO; |
599 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); | 613 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); |
600 raise(SIGBUS); | 614 raise(SIGBUS); |
601 char c = '\000'; | 615 char c = '\000'; |
602 BPF_ASSERT(read(fds[0], &c, 1) == 1); | 616 BPF_ASSERT(read(fds[0], &c, 1) == 1); |
603 BPF_ASSERT(close(fds[0]) == 0); | 617 BPF_ASSERT(close(fds[0]) == 0); |
604 BPF_ASSERT(close(fds[1]) == 0); | 618 BPF_ASSERT(close(fds[1]) == 0); |
605 BPF_ASSERT(c == 0x55); | 619 BPF_ASSERT(c == 0x55); |
606 } | 620 } |
(...skipping 15 matching lines...) Expand all Loading... |
622 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. | 636 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. |
623 sigemptyset(&mask0); | 637 sigemptyset(&mask0); |
624 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); | 638 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); |
625 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); | 639 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); |
626 | 640 |
627 // Try again, and this time we verify that we can block it. This | 641 // Try again, and this time we verify that we can block it. This |
628 // requires a second call to sigprocmask(). | 642 // requires a second call to sigprocmask(). |
629 sigaddset(&mask0, SIGUSR2); | 643 sigaddset(&mask0, SIGUSR2); |
630 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); | 644 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); |
631 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); | 645 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); |
632 BPF_ASSERT( sigismember(&mask2, SIGUSR2)); | 646 BPF_ASSERT(sigismember(&mask2, SIGUSR2)); |
633 } | 647 } |
634 | 648 |
635 BPF_TEST(SandboxBpf, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { | 649 BPF_TEST(SandboxBpf, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { |
636 // An UnsafeTrap() (or for that matter, a Trap()) has to report error | 650 // An UnsafeTrap() (or for that matter, a Trap()) has to report error |
637 // conditions by returning an exit code in the range -1..-4096. This | 651 // conditions by returning an exit code in the range -1..-4096. This |
638 // should happen automatically if using ForwardSyscall(). If the TrapFnc() | 652 // should happen automatically if using ForwardSyscall(). If the TrapFnc() |
639 // uses some other method to make system calls, then it is responsible | 653 // uses some other method to make system calls, then it is responsible |
640 // for computing the correct return code. | 654 // for computing the correct return code. |
641 // This test verifies that ForwardSyscall() does the correct thing. | 655 // This test verifies that ForwardSyscall() does the correct thing. |
642 | 656 |
643 // The glibc system wrapper will ultimately set errno for us. So, from normal | 657 // The glibc system wrapper will ultimately set errno for us. So, from normal |
644 // userspace, all of this should be completely transparent. | 658 // userspace, all of this should be completely transparent. |
645 errno = 0; | 659 errno = 0; |
646 BPF_ASSERT(close(-1) == -1); | 660 BPF_ASSERT(close(-1) == -1); |
647 BPF_ASSERT(errno == EBADF); | 661 BPF_ASSERT(errno == EBADF); |
648 | 662 |
649 // Explicitly avoid the glibc wrapper. This is not normally the way anybody | 663 // Explicitly avoid the glibc wrapper. This is not normally the way anybody |
650 // would make system calls, but it allows us to verify that we don't | 664 // would make system calls, but it allows us to verify that we don't |
651 // accidentally mess with errno, when we shouldn't. | 665 // accidentally mess with errno, when we shouldn't. |
652 errno = 0; | 666 errno = 0; |
653 struct arch_seccomp_data args = { }; | 667 struct arch_seccomp_data args = {}; |
654 args.nr = __NR_close; | 668 args.nr = __NR_close; |
655 args.args[0] = -1; | 669 args.args[0] = -1; |
656 BPF_ASSERT(Sandbox::ForwardSyscall(args) == -EBADF); | 670 BPF_ASSERT(Sandbox::ForwardSyscall(args) == -EBADF); |
657 BPF_ASSERT(errno == 0); | 671 BPF_ASSERT(errno == 0); |
658 } | 672 } |
659 | 673 |
660 // Test a trap handler that makes use of a broker process to open(). | 674 // Test a trap handler that makes use of a broker process to open(). |
661 | 675 |
662 class InitializedOpenBroker { | 676 class InitializedOpenBroker { |
663 public: | 677 public: |
664 InitializedOpenBroker() : initialized_(false) { | 678 InitializedOpenBroker() : initialized_(false) { |
665 std::vector<std::string> allowed_files; | 679 std::vector<std::string> allowed_files; |
666 allowed_files.push_back("/proc/allowed"); | 680 allowed_files.push_back("/proc/allowed"); |
667 allowed_files.push_back("/proc/cpuinfo"); | 681 allowed_files.push_back("/proc/cpuinfo"); |
668 | 682 |
669 broker_process_.reset(new BrokerProcess(EPERM, | 683 broker_process_.reset( |
670 allowed_files, | 684 new BrokerProcess(EPERM, allowed_files, std::vector<std::string>())); |
671 std::vector<std::string>())); | |
672 BPF_ASSERT(broker_process() != NULL); | 685 BPF_ASSERT(broker_process() != NULL); |
673 BPF_ASSERT(broker_process_->Init(NULL)); | 686 BPF_ASSERT(broker_process_->Init(NULL)); |
674 | 687 |
675 initialized_ = true; | 688 initialized_ = true; |
676 } | 689 } |
677 bool initialized() { return initialized_; } | 690 bool initialized() { return initialized_; } |
678 class BrokerProcess* broker_process() { return broker_process_.get(); } | 691 class BrokerProcess* broker_process() { return broker_process_.get(); } |
| 692 |
679 private: | 693 private: |
680 bool initialized_; | 694 bool initialized_; |
681 scoped_ptr<class BrokerProcess> broker_process_; | 695 scoped_ptr<class BrokerProcess> broker_process_; |
682 DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker); | 696 DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker); |
683 }; | 697 }; |
684 | 698 |
685 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args, | 699 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args, |
686 void *aux) { | 700 void* aux) { |
687 BPF_ASSERT(aux); | 701 BPF_ASSERT(aux); |
688 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux); | 702 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux); |
689 switch(args.nr) { | 703 switch (args.nr) { |
690 case __NR_access: | 704 case __NR_access: |
691 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), | 705 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]), |
692 static_cast<int>(args.args[1])); | 706 static_cast<int>(args.args[1])); |
693 case __NR_open: | 707 case __NR_open: |
694 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]), | 708 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]), |
695 static_cast<int>(args.args[1])); | 709 static_cast<int>(args.args[1])); |
696 case __NR_openat: | 710 case __NR_openat: |
697 // We only call open() so if we arrive here, it's because glibc uses | 711 // We only call open() so if we arrive here, it's because glibc uses |
698 // the openat() system call. | 712 // the openat() system call. |
699 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); | 713 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD); |
700 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), | 714 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]), |
701 static_cast<int>(args.args[2])); | 715 static_cast<int>(args.args[2])); |
702 default: | 716 default: |
703 BPF_ASSERT(false); | 717 BPF_ASSERT(false); |
704 return -ENOSYS; | 718 return -ENOSYS; |
705 } | 719 } |
706 } | 720 } |
707 | 721 |
708 ErrorCode DenyOpenPolicy(Sandbox *sandbox, int sysno, void *aux) { | 722 ErrorCode DenyOpenPolicy(Sandbox* sandbox, int sysno, void* aux) { |
709 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux); | 723 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux); |
710 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 724 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
711 return ErrorCode(ENOSYS); | 725 return ErrorCode(ENOSYS); |
712 } | 726 } |
713 | 727 |
714 switch (sysno) { | 728 switch (sysno) { |
715 case __NR_access: | 729 case __NR_access: |
716 case __NR_open: | 730 case __NR_open: |
717 case __NR_openat: | 731 case __NR_openat: |
718 // We get a InitializedOpenBroker class, but our trap handler wants | 732 // We get a InitializedOpenBroker class, but our trap handler wants |
719 // the BrokerProcess object. | 733 // the BrokerProcess object. |
720 return ErrorCode(sandbox->Trap(BrokerOpenTrapHandler, | 734 return ErrorCode( |
721 iob->broker_process())); | 735 sandbox->Trap(BrokerOpenTrapHandler, iob->broker_process())); |
722 default: | 736 default: |
723 return ErrorCode(ErrorCode::ERR_ALLOWED); | 737 return ErrorCode(ErrorCode::ERR_ALLOWED); |
724 } | 738 } |
725 } | 739 } |
726 | 740 |
727 // We use a InitializedOpenBroker class, so that we can run unsandboxed | 741 // We use a InitializedOpenBroker class, so that we can run unsandboxed |
728 // code in its constructor, which is the only way to do so in a BPF_TEST. | 742 // code in its constructor, which is the only way to do so in a BPF_TEST. |
729 BPF_TEST(SandboxBpf, UseOpenBroker, DenyOpenPolicy, | 743 BPF_TEST(SandboxBpf, |
| 744 UseOpenBroker, |
| 745 DenyOpenPolicy, |
730 InitializedOpenBroker /* BPF_AUX */) { | 746 InitializedOpenBroker /* BPF_AUX */) { |
731 BPF_ASSERT(BPF_AUX.initialized()); | 747 BPF_ASSERT(BPF_AUX.initialized()); |
732 BrokerProcess* broker_process = BPF_AUX.broker_process(); | 748 BrokerProcess* broker_process = BPF_AUX.broker_process(); |
733 BPF_ASSERT(broker_process != NULL); | 749 BPF_ASSERT(broker_process != NULL); |
734 | 750 |
735 // First, use the broker "manually" | 751 // First, use the broker "manually" |
736 BPF_ASSERT(broker_process->Open("/proc/denied", O_RDONLY) == -EPERM); | 752 BPF_ASSERT(broker_process->Open("/proc/denied", O_RDONLY) == -EPERM); |
737 BPF_ASSERT(broker_process->Access("/proc/denied", R_OK) == -EPERM); | 753 BPF_ASSERT(broker_process->Access("/proc/denied", R_OK) == -EPERM); |
738 BPF_ASSERT(broker_process->Open("/proc/allowed", O_RDONLY) == -ENOENT); | 754 BPF_ASSERT(broker_process->Open("/proc/allowed", O_RDONLY) == -ENOENT); |
739 BPF_ASSERT(broker_process->Access("/proc/allowed", R_OK) == -ENOENT); | 755 BPF_ASSERT(broker_process->Access("/proc/allowed", R_OK) == -ENOENT); |
740 | 756 |
741 // Now use glibc's open() as an external library would. | 757 // Now use glibc's open() as an external library would. |
742 BPF_ASSERT(open("/proc/denied", O_RDONLY) == -1); | 758 BPF_ASSERT(open("/proc/denied", O_RDONLY) == -1); |
(...skipping 21 matching lines...) Expand all Loading... |
764 int cpu_info_access = access("/proc/cpuinfo", R_OK); | 780 int cpu_info_access = access("/proc/cpuinfo", R_OK); |
765 BPF_ASSERT(cpu_info_access == 0); | 781 BPF_ASSERT(cpu_info_access == 0); |
766 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); | 782 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); |
767 BPF_ASSERT(cpu_info_fd >= 0); | 783 BPF_ASSERT(cpu_info_fd >= 0); |
768 char buf[1024]; | 784 char buf[1024]; |
769 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); | 785 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); |
770 } | 786 } |
771 | 787 |
772 // Simple test demonstrating how to use Sandbox::Cond() | 788 // Simple test demonstrating how to use Sandbox::Cond() |
773 | 789 |
774 ErrorCode SimpleCondTestPolicy(Sandbox *sandbox, int sysno, void *) { | 790 ErrorCode SimpleCondTestPolicy(Sandbox* sandbox, int sysno, void*) { |
775 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 791 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
776 // FIXME: we should really not have to do that in a trivial policy | 792 // FIXME: we should really not have to do that in a trivial policy |
777 return ErrorCode(ENOSYS); | 793 return ErrorCode(ENOSYS); |
778 } | 794 } |
779 | 795 |
780 // We deliberately return unusual errno values upon failure, so that we | 796 // We deliberately return unusual errno values upon failure, so that we |
781 // can uniquely test for these values. In a "real" policy, you would want | 797 // can uniquely test for these values. In a "real" policy, you would want |
782 // to return more traditional values. | 798 // to return more traditional values. |
783 switch (sysno) { | 799 switch (sysno) { |
784 case __NR_open: | 800 case __NR_open: |
785 // Allow opening files for reading, but don't allow writing. | 801 // Allow opening files for reading, but don't allow writing. |
786 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); | 802 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); |
787 return sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 803 return sandbox->Cond(1, |
| 804 ErrorCode::TP_32BIT, |
| 805 ErrorCode::OP_HAS_ANY_BITS, |
788 O_ACCMODE /* 0x3 */, | 806 O_ACCMODE /* 0x3 */, |
789 ErrorCode(EROFS), | 807 ErrorCode(EROFS), |
790 ErrorCode(ErrorCode::ERR_ALLOWED)); | 808 ErrorCode(ErrorCode::ERR_ALLOWED)); |
791 case __NR_prctl: | 809 case __NR_prctl: |
792 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but | 810 // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but |
793 // disallow everything else. | 811 // disallow everything else. |
794 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 812 return sandbox->Cond(0, |
| 813 ErrorCode::TP_32BIT, |
| 814 ErrorCode::OP_EQUAL, |
795 PR_SET_DUMPABLE, | 815 PR_SET_DUMPABLE, |
796 ErrorCode(ErrorCode::ERR_ALLOWED), | 816 ErrorCode(ErrorCode::ERR_ALLOWED), |
797 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 817 sandbox->Cond(0, |
798 PR_GET_DUMPABLE, | 818 ErrorCode::TP_32BIT, |
799 ErrorCode(ErrorCode::ERR_ALLOWED), | 819 ErrorCode::OP_EQUAL, |
800 ErrorCode(ENOMEM))); | 820 PR_GET_DUMPABLE, |
| 821 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 822 ErrorCode(ENOMEM))); |
801 default: | 823 default: |
802 return ErrorCode(ErrorCode::ERR_ALLOWED); | 824 return ErrorCode(ErrorCode::ERR_ALLOWED); |
803 } | 825 } |
804 } | 826 } |
805 | 827 |
806 BPF_TEST(SandboxBpf, SimpleCondTest, SimpleCondTestPolicy) { | 828 BPF_TEST(SandboxBpf, SimpleCondTest, SimpleCondTestPolicy) { |
807 int fd; | 829 int fd; |
808 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); | 830 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); |
809 BPF_ASSERT(errno == EROFS); | 831 BPF_ASSERT(errno == EROFS); |
810 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); | 832 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); |
811 close(fd); | 833 close(fd); |
812 | 834 |
813 int ret; | 835 int ret; |
814 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); | 836 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); |
815 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1-ret) == 0); | 837 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0); |
816 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); | 838 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); |
817 BPF_ASSERT(errno == ENOMEM); | 839 BPF_ASSERT(errno == ENOMEM); |
818 } | 840 } |
819 | 841 |
820 // This test exercises the Sandbox::Cond() method by building a complex | 842 // This test exercises the Sandbox::Cond() method by building a complex |
821 // tree of conditional equality operations. It then makes system calls and | 843 // tree of conditional equality operations. It then makes system calls and |
822 // verifies that they return the values that we expected from our BPF | 844 // verifies that they return the values that we expected from our BPF |
823 // program. | 845 // program. |
824 class EqualityStressTest { | 846 class EqualityStressTest { |
825 public: | 847 public: |
826 EqualityStressTest() { | 848 EqualityStressTest() { |
827 // We want a deterministic test | 849 // We want a deterministic test |
828 srand(0); | 850 srand(0); |
829 | 851 |
830 // Iterates over system call numbers and builds a random tree of | 852 // Iterates over system call numbers and builds a random tree of |
831 // equality tests. | 853 // equality tests. |
832 // We are actually constructing a graph of ArgValue objects. This | 854 // We are actually constructing a graph of ArgValue objects. This |
833 // graph will later be used to a) compute our sandbox policy, and | 855 // graph will later be used to a) compute our sandbox policy, and |
834 // b) drive the code that verifies the output from the BPF program. | 856 // b) drive the code that verifies the output from the BPF program. |
835 COMPILE_ASSERT(kNumTestCases < (int)(MAX_PUBLIC_SYSCALL-MIN_SYSCALL-10), | 857 COMPILE_ASSERT( |
836 num_test_cases_must_be_significantly_smaller_than_num_system_calls); | 858 kNumTestCases < (int)(MAX_PUBLIC_SYSCALL - MIN_SYSCALL - 10), |
| 859 num_test_cases_must_be_significantly_smaller_than_num_system_calls); |
837 for (int sysno = MIN_SYSCALL, end = kNumTestCases; sysno < end; ++sysno) { | 860 for (int sysno = MIN_SYSCALL, end = kNumTestCases; sysno < end; ++sysno) { |
838 if (IsReservedSyscall(sysno)) { | 861 if (IsReservedSyscall(sysno)) { |
839 // Skip reserved system calls. This ensures that our test frame | 862 // Skip reserved system calls. This ensures that our test frame |
840 // work isn't impacted by the fact that we are overriding | 863 // work isn't impacted by the fact that we are overriding |
841 // a lot of different system calls. | 864 // a lot of different system calls. |
842 ++end; | 865 ++end; |
843 arg_values_.push_back(NULL); | 866 arg_values_.push_back(NULL); |
844 } else { | 867 } else { |
845 arg_values_.push_back(RandomArgValue(rand() % kMaxArgs, 0, | 868 arg_values_.push_back( |
846 rand() % kMaxArgs)); | 869 RandomArgValue(rand() % kMaxArgs, 0, rand() % kMaxArgs)); |
847 } | 870 } |
848 } | 871 } |
849 } | 872 } |
850 | 873 |
851 ~EqualityStressTest() { | 874 ~EqualityStressTest() { |
852 for (std::vector<ArgValue *>::iterator iter = arg_values_.begin(); | 875 for (std::vector<ArgValue*>::iterator iter = arg_values_.begin(); |
853 iter != arg_values_.end(); | 876 iter != arg_values_.end(); |
854 ++iter) { | 877 ++iter) { |
855 DeleteArgValue(*iter); | 878 DeleteArgValue(*iter); |
856 } | 879 } |
857 } | 880 } |
858 | 881 |
859 ErrorCode Policy(Sandbox *sandbox, int sysno) { | 882 ErrorCode Policy(Sandbox* sandbox, int sysno) { |
860 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 883 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
861 // FIXME: we should really not have to do that in a trivial policy | 884 // FIXME: we should really not have to do that in a trivial policy |
862 return ErrorCode(ENOSYS); | 885 return ErrorCode(ENOSYS); |
863 } else if (sysno < 0 || sysno >= (int)arg_values_.size() || | 886 } else if (sysno < 0 || sysno >= (int)arg_values_.size() || |
864 IsReservedSyscall(sysno)) { | 887 IsReservedSyscall(sysno)) { |
865 // We only return ErrorCode values for the system calls that | 888 // We only return ErrorCode values for the system calls that |
866 // are part of our test data. Every other system call remains | 889 // are part of our test data. Every other system call remains |
867 // allowed. | 890 // allowed. |
868 return ErrorCode(ErrorCode::ERR_ALLOWED); | 891 return ErrorCode(ErrorCode::ERR_ALLOWED); |
869 } else { | 892 } else { |
(...skipping 11 matching lines...) Expand all Loading... |
881 // Skip reserved system calls. | 904 // Skip reserved system calls. |
882 continue; | 905 continue; |
883 } | 906 } |
884 // Verify that system calls return the values that we expect them to | 907 // Verify that system calls return the values that we expect them to |
885 // return. This involves passing different combinations of system call | 908 // return. This involves passing different combinations of system call |
886 // parameters in order to exercise all possible code paths through the | 909 // parameters in order to exercise all possible code paths through the |
887 // BPF filter program. | 910 // BPF filter program. |
888 // We arbitrarily start by setting all six system call arguments to | 911 // We arbitrarily start by setting all six system call arguments to |
889 // zero. And we then recursive traverse our tree of ArgValues to | 912 // zero. And we then recursive traverse our tree of ArgValues to |
890 // determine the necessary combinations of parameters. | 913 // determine the necessary combinations of parameters. |
891 intptr_t args[6] = { }; | 914 intptr_t args[6] = {}; |
892 Verify(sysno, args, *arg_values_[sysno]); | 915 Verify(sysno, args, *arg_values_[sysno]); |
893 } | 916 } |
894 } | 917 } |
895 | 918 |
896 private: | 919 private: |
897 struct ArgValue { | 920 struct ArgValue { |
898 int argno; // Argument number to inspect. | 921 int argno; // Argument number to inspect. |
899 int size; // Number of test cases (must be > 0). | 922 int size; // Number of test cases (must be > 0). |
900 struct Tests { | 923 struct Tests { |
901 uint32_t k_value; // Value to compare syscall arg against. | 924 uint32_t k_value; // Value to compare syscall arg against. |
902 int err; // If non-zero, errno value to return. | 925 int err; // If non-zero, errno value to return. |
903 struct ArgValue *arg_value; // Otherwise, more args needs inspecting. | 926 struct ArgValue* arg_value; // Otherwise, more args needs inspecting. |
904 } *tests; | 927 }* tests; |
905 int err; // If none of the tests passed, this is what | 928 int err; // If none of the tests passed, this is what |
906 struct ArgValue *arg_value; // we'll return (this is the "else" branch). | 929 struct ArgValue* arg_value; // we'll return (this is the "else" branch). |
907 }; | 930 }; |
908 | 931 |
909 bool IsReservedSyscall(int sysno) { | 932 bool IsReservedSyscall(int sysno) { |
910 // There are a handful of system calls that we should never use in our | 933 // There are a handful of system calls that we should never use in our |
911 // test cases. These system calls are needed to allow the test framework | 934 // test cases. These system calls are needed to allow the test framework |
912 // to run properly. | 935 // to run properly. |
913 // If we wanted to write fully generic code, there are more system calls | 936 // If we wanted to write fully generic code, there are more system calls |
914 // that could be listed here, and it is quite difficult to come up with a | 937 // that could be listed here, and it is quite difficult to come up with a |
915 // truly comprehensive list. After all, we are deliberately making system | 938 // truly comprehensive list. After all, we are deliberately making system |
916 // calls unavailable. In practice, we have a pretty good idea of the system | 939 // calls unavailable. In practice, we have a pretty good idea of the system |
917 // calls that will be made by this particular test. So, this small list is | 940 // calls that will be made by this particular test. So, this small list is |
918 // sufficient. But if anybody copy'n'pasted this code for other uses, they | 941 // sufficient. But if anybody copy'n'pasted this code for other uses, they |
919 // would have to review that the list. | 942 // would have to review that the list. |
920 return sysno == __NR_read || | 943 return sysno == __NR_read || sysno == __NR_write || sysno == __NR_exit || |
921 sysno == __NR_write || | 944 sysno == __NR_exit_group || sysno == __NR_restart_syscall; |
922 sysno == __NR_exit || | |
923 sysno == __NR_exit_group || | |
924 sysno == __NR_restart_syscall; | |
925 } | 945 } |
926 | 946 |
927 ArgValue *RandomArgValue(int argno, int args_mask, int remaining_args) { | 947 ArgValue* RandomArgValue(int argno, int args_mask, int remaining_args) { |
928 // Create a new ArgValue and fill it with random data. We use as bit mask | 948 // Create a new ArgValue and fill it with random data. We use as bit mask |
929 // to keep track of the system call parameters that have previously been | 949 // to keep track of the system call parameters that have previously been |
930 // set; this ensures that we won't accidentally define a contradictory | 950 // set; this ensures that we won't accidentally define a contradictory |
931 // set of equality tests. | 951 // set of equality tests. |
932 struct ArgValue *arg_value = new ArgValue(); | 952 struct ArgValue* arg_value = new ArgValue(); |
933 args_mask |= 1 << argno; | 953 args_mask |= 1 << argno; |
934 arg_value->argno = argno; | 954 arg_value->argno = argno; |
935 | 955 |
936 // Apply some restrictions on just how complex our tests can be. | 956 // Apply some restrictions on just how complex our tests can be. |
937 // Otherwise, we end up with a BPF program that is too complicated for | 957 // Otherwise, we end up with a BPF program that is too complicated for |
938 // the kernel to load. | 958 // the kernel to load. |
939 int fan_out = kMaxFanOut; | 959 int fan_out = kMaxFanOut; |
940 if (remaining_args > 3) { | 960 if (remaining_args > 3) { |
941 fan_out = 1; | 961 fan_out = 1; |
942 } else if (remaining_args > 2) { | 962 } else if (remaining_args > 2) { |
943 fan_out = 2; | 963 fan_out = 2; |
944 } | 964 } |
945 | 965 |
946 // Create a couple of different test cases with randomized values that | 966 // Create a couple of different test cases with randomized values that |
947 // we want to use when comparing system call parameter number "argno". | 967 // we want to use when comparing system call parameter number "argno". |
948 arg_value->size = rand() % fan_out + 1; | 968 arg_value->size = rand() % fan_out + 1; |
949 arg_value->tests = new ArgValue::Tests[arg_value->size]; | 969 arg_value->tests = new ArgValue::Tests[arg_value->size]; |
950 | 970 |
951 uint32_t k_value = rand(); | 971 uint32_t k_value = rand(); |
952 for (int n = 0; n < arg_value->size; ++n) { | 972 for (int n = 0; n < arg_value->size; ++n) { |
953 // Ensure that we have unique values | 973 // Ensure that we have unique values |
954 k_value += rand() % (RAND_MAX/(kMaxFanOut+1)) + 1; | 974 k_value += rand() % (RAND_MAX / (kMaxFanOut + 1)) + 1; |
955 | 975 |
956 // There are two possible types of nodes. Either this is a leaf node; | 976 // There are two possible types of nodes. Either this is a leaf node; |
957 // in that case, we have completed all the equality tests that we | 977 // in that case, we have completed all the equality tests that we |
958 // wanted to perform, and we can now compute a random "errno" value that | 978 // wanted to perform, and we can now compute a random "errno" value that |
959 // we should return. Or this is part of a more complex boolean | 979 // we should return. Or this is part of a more complex boolean |
960 // expression; in that case, we have to recursively add tests for some | 980 // expression; in that case, we have to recursively add tests for some |
961 // of system call parameters that we have not yet included in our | 981 // of system call parameters that we have not yet included in our |
962 // tests. | 982 // tests. |
963 arg_value->tests[n].k_value = k_value; | 983 arg_value->tests[n].k_value = k_value; |
964 if (!remaining_args || (rand() & 1)) { | 984 if (!remaining_args || (rand() & 1)) { |
965 arg_value->tests[n].err = (rand() % 1000) + 1; | 985 arg_value->tests[n].err = (rand() % 1000) + 1; |
966 arg_value->tests[n].arg_value = NULL; | 986 arg_value->tests[n].arg_value = NULL; |
967 } else { | 987 } else { |
968 arg_value->tests[n].err = 0; | 988 arg_value->tests[n].err = 0; |
969 arg_value->tests[n].arg_value = | 989 arg_value->tests[n].arg_value = |
970 RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1); | 990 RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1); |
971 } | 991 } |
972 } | 992 } |
973 // Finally, we have to define what we should return if none of the | 993 // Finally, we have to define what we should return if none of the |
974 // previous equality tests pass. Again, we can either deal with a leaf | 994 // previous equality tests pass. Again, we can either deal with a leaf |
975 // node, or we can randomly add another couple of tests. | 995 // node, or we can randomly add another couple of tests. |
976 if (!remaining_args || (rand() & 1)) { | 996 if (!remaining_args || (rand() & 1)) { |
977 arg_value->err = (rand() % 1000) + 1; | 997 arg_value->err = (rand() % 1000) + 1; |
978 arg_value->arg_value = NULL; | 998 arg_value->arg_value = NULL; |
979 } else { | 999 } else { |
980 arg_value->err = 0; | 1000 arg_value->err = 0; |
981 arg_value->arg_value = | 1001 arg_value->arg_value = |
982 RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1); | 1002 RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1); |
983 } | 1003 } |
984 // We have now built a new (sub-)tree of ArgValues defining a set of | 1004 // We have now built a new (sub-)tree of ArgValues defining a set of |
985 // boolean expressions for testing random system call arguments against | 1005 // boolean expressions for testing random system call arguments against |
986 // random values. Return this tree to our caller. | 1006 // random values. Return this tree to our caller. |
987 return arg_value; | 1007 return arg_value; |
988 } | 1008 } |
989 | 1009 |
990 int RandomArg(int args_mask) { | 1010 int RandomArg(int args_mask) { |
991 // Compute a random system call parameter number. | 1011 // Compute a random system call parameter number. |
992 int argno = rand() % kMaxArgs; | 1012 int argno = rand() % kMaxArgs; |
993 | 1013 |
994 // Make sure that this same parameter number has not previously been | 1014 // Make sure that this same parameter number has not previously been |
995 // used. Otherwise, we could end up with a test that is impossible to | 1015 // used. Otherwise, we could end up with a test that is impossible to |
996 // satisfy (e.g. args[0] == 1 && args[0] == 2). | 1016 // satisfy (e.g. args[0] == 1 && args[0] == 2). |
997 while (args_mask & (1 << argno)) { | 1017 while (args_mask & (1 << argno)) { |
998 argno = (argno + 1) % kMaxArgs; | 1018 argno = (argno + 1) % kMaxArgs; |
999 } | 1019 } |
1000 return argno; | 1020 return argno; |
1001 } | 1021 } |
1002 | 1022 |
1003 void DeleteArgValue(ArgValue *arg_value) { | 1023 void DeleteArgValue(ArgValue* arg_value) { |
1004 // Delete an ArgValue and all of its child nodes. This requires | 1024 // Delete an ArgValue and all of its child nodes. This requires |
1005 // recursively descending into the tree. | 1025 // recursively descending into the tree. |
1006 if (arg_value) { | 1026 if (arg_value) { |
1007 if (arg_value->size) { | 1027 if (arg_value->size) { |
1008 for (int n = 0; n < arg_value->size; ++n) { | 1028 for (int n = 0; n < arg_value->size; ++n) { |
1009 if (!arg_value->tests[n].err) { | 1029 if (!arg_value->tests[n].err) { |
1010 DeleteArgValue(arg_value->tests[n].arg_value); | 1030 DeleteArgValue(arg_value->tests[n].arg_value); |
1011 } | 1031 } |
1012 } | 1032 } |
1013 delete[] arg_value->tests; | 1033 delete[] arg_value->tests; |
1014 } | 1034 } |
1015 if (!arg_value->err) { | 1035 if (!arg_value->err) { |
1016 DeleteArgValue(arg_value->arg_value); | 1036 DeleteArgValue(arg_value->arg_value); |
1017 } | 1037 } |
1018 delete arg_value; | 1038 delete arg_value; |
1019 } | 1039 } |
1020 } | 1040 } |
1021 | 1041 |
1022 ErrorCode ToErrorCode(Sandbox *sandbox, ArgValue *arg_value) { | 1042 ErrorCode ToErrorCode(Sandbox* sandbox, ArgValue* arg_value) { |
1023 // Compute the ErrorCode that should be returned, if none of our | 1043 // Compute the ErrorCode that should be returned, if none of our |
1024 // tests succeed (i.e. the system call parameter doesn't match any | 1044 // tests succeed (i.e. the system call parameter doesn't match any |
1025 // of the values in arg_value->tests[].k_value). | 1045 // of the values in arg_value->tests[].k_value). |
1026 ErrorCode err; | 1046 ErrorCode err; |
1027 if (arg_value->err) { | 1047 if (arg_value->err) { |
1028 // If this was a leaf node, return the errno value that we expect to | 1048 // If this was a leaf node, return the errno value that we expect to |
1029 // return from the BPF filter program. | 1049 // return from the BPF filter program. |
1030 err = ErrorCode(arg_value->err); | 1050 err = ErrorCode(arg_value->err); |
1031 } else { | 1051 } else { |
1032 // If this wasn't a leaf node yet, recursively descend into the rest | 1052 // If this wasn't a leaf node yet, recursively descend into the rest |
1033 // of the tree. This will end up adding a few more Sandbox::Cond() | 1053 // of the tree. This will end up adding a few more Sandbox::Cond() |
1034 // tests to our ErrorCode. | 1054 // tests to our ErrorCode. |
1035 err = ToErrorCode(sandbox, arg_value->arg_value); | 1055 err = ToErrorCode(sandbox, arg_value->arg_value); |
1036 } | 1056 } |
1037 | 1057 |
1038 // Now, iterate over all the test cases that we want to compare against. | 1058 // Now, iterate over all the test cases that we want to compare against. |
1039 // This builds a chain of Sandbox::Cond() tests | 1059 // This builds a chain of Sandbox::Cond() tests |
1040 // (aka "if ... elif ... elif ... elif ... fi") | 1060 // (aka "if ... elif ... elif ... elif ... fi") |
1041 for (int n = arg_value->size; n-- > 0; ) { | 1061 for (int n = arg_value->size; n-- > 0;) { |
1042 ErrorCode matched; | 1062 ErrorCode matched; |
1043 // Again, we distinguish between leaf nodes and subtrees. | 1063 // Again, we distinguish between leaf nodes and subtrees. |
1044 if (arg_value->tests[n].err) { | 1064 if (arg_value->tests[n].err) { |
1045 matched = ErrorCode(arg_value->tests[n].err); | 1065 matched = ErrorCode(arg_value->tests[n].err); |
1046 } else { | 1066 } else { |
1047 matched = ToErrorCode(sandbox, arg_value->tests[n].arg_value); | 1067 matched = ToErrorCode(sandbox, arg_value->tests[n].arg_value); |
1048 } | 1068 } |
1049 // For now, all of our tests are limited to 32bit. | 1069 // For now, all of our tests are limited to 32bit. |
1050 // We have separate tests that check the behavior of 32bit vs. 64bit | 1070 // We have separate tests that check the behavior of 32bit vs. 64bit |
1051 // conditional expressions. | 1071 // conditional expressions. |
1052 err = sandbox->Cond(arg_value->argno, ErrorCode::TP_32BIT, | 1072 err = sandbox->Cond(arg_value->argno, |
1053 ErrorCode::OP_EQUAL, arg_value->tests[n].k_value, | 1073 ErrorCode::TP_32BIT, |
1054 matched, err); | 1074 ErrorCode::OP_EQUAL, |
| 1075 arg_value->tests[n].k_value, |
| 1076 matched, |
| 1077 err); |
1055 } | 1078 } |
1056 return err; | 1079 return err; |
1057 } | 1080 } |
1058 | 1081 |
1059 void Verify(int sysno, intptr_t *args, const ArgValue& arg_value) { | 1082 void Verify(int sysno, intptr_t* args, const ArgValue& arg_value) { |
1060 uint32_t mismatched = 0; | 1083 uint32_t mismatched = 0; |
1061 // Iterate over all the k_values in arg_value.tests[] and verify that | 1084 // Iterate over all the k_values in arg_value.tests[] and verify that |
1062 // we see the expected return values from system calls, when we pass | 1085 // we see the expected return values from system calls, when we pass |
1063 // the k_value as a parameter in a system call. | 1086 // the k_value as a parameter in a system call. |
1064 for (int n = arg_value.size; n-- > 0; ) { | 1087 for (int n = arg_value.size; n-- > 0;) { |
1065 mismatched += arg_value.tests[n].k_value; | 1088 mismatched += arg_value.tests[n].k_value; |
1066 args[arg_value.argno] = arg_value.tests[n].k_value; | 1089 args[arg_value.argno] = arg_value.tests[n].k_value; |
1067 if (arg_value.tests[n].err) { | 1090 if (arg_value.tests[n].err) { |
1068 VerifyErrno(sysno, args, arg_value.tests[n].err); | 1091 VerifyErrno(sysno, args, arg_value.tests[n].err); |
1069 } else { | 1092 } else { |
1070 Verify(sysno, args, *arg_value.tests[n].arg_value); | 1093 Verify(sysno, args, *arg_value.tests[n].arg_value); |
1071 } | 1094 } |
1072 } | 1095 } |
1073 // Find a k_value that doesn't match any of the k_values in | 1096 // Find a k_value that doesn't match any of the k_values in |
1074 // arg_value.tests[]. In most cases, the current value of "mismatched" | 1097 // arg_value.tests[]. In most cases, the current value of "mismatched" |
1075 // would fit this requirement. But on the off-chance that it happens | 1098 // would fit this requirement. But on the off-chance that it happens |
1076 // to collide, we double-check. | 1099 // to collide, we double-check. |
1077 try_again: | 1100 try_again: |
1078 for (int n = arg_value.size; n-- > 0; ) { | 1101 for (int n = arg_value.size; n-- > 0;) { |
1079 if (mismatched == arg_value.tests[n].k_value) { | 1102 if (mismatched == arg_value.tests[n].k_value) { |
1080 ++mismatched; | 1103 ++mismatched; |
1081 goto try_again; | 1104 goto try_again; |
1082 } | 1105 } |
1083 } | 1106 } |
1084 // Now verify that we see the expected return value from system calls, | 1107 // Now verify that we see the expected return value from system calls, |
1085 // if we pass a value that doesn't match any of the conditions (i.e. this | 1108 // if we pass a value that doesn't match any of the conditions (i.e. this |
1086 // is testing the "else" clause of the conditions). | 1109 // is testing the "else" clause of the conditions). |
1087 args[arg_value.argno] = mismatched; | 1110 args[arg_value.argno] = mismatched; |
1088 if (arg_value.err) { | 1111 if (arg_value.err) { |
1089 VerifyErrno(sysno, args, arg_value.err); | 1112 VerifyErrno(sysno, args, arg_value.err); |
1090 } else { | 1113 } else { |
1091 Verify(sysno, args, *arg_value.arg_value); | 1114 Verify(sysno, args, *arg_value.arg_value); |
1092 } | 1115 } |
1093 // Reset args[arg_value.argno]. This is not technically needed, but it | 1116 // Reset args[arg_value.argno]. This is not technically needed, but it |
1094 // makes it easier to reason about the correctness of our tests. | 1117 // makes it easier to reason about the correctness of our tests. |
1095 args[arg_value.argno] = 0; | 1118 args[arg_value.argno] = 0; |
1096 } | 1119 } |
1097 | 1120 |
1098 void VerifyErrno(int sysno, intptr_t *args, int err) { | 1121 void VerifyErrno(int sysno, intptr_t* args, int err) { |
1099 // We installed BPF filters that return different errno values | 1122 // We installed BPF filters that return different errno values |
1100 // based on the system call number and the parameters that we decided | 1123 // based on the system call number and the parameters that we decided |
1101 // to pass in. Verify that this condition holds true. | 1124 // to pass in. Verify that this condition holds true. |
1102 BPF_ASSERT(SandboxSyscall(sysno, | 1125 BPF_ASSERT( |
1103 args[0], args[1], args[2], | 1126 SandboxSyscall( |
1104 args[3], args[4], args[5]) == -err); | 1127 sysno, args[0], args[1], args[2], args[3], args[4], args[5]) == |
| 1128 -err); |
1105 } | 1129 } |
1106 | 1130 |
1107 // Vector of ArgValue trees. These trees define all the possible boolean | 1131 // Vector of ArgValue trees. These trees define all the possible boolean |
1108 // expressions that we want to turn into a BPF filter program. | 1132 // expressions that we want to turn into a BPF filter program. |
1109 std::vector<ArgValue *> arg_values_; | 1133 std::vector<ArgValue*> arg_values_; |
1110 | 1134 |
1111 // Don't increase these values. We are pushing the limits of the maximum | 1135 // Don't increase these values. We are pushing the limits of the maximum |
1112 // BPF program that the kernel will allow us to load. If the values are | 1136 // BPF program that the kernel will allow us to load. If the values are |
1113 // increased too much, the test will start failing. | 1137 // increased too much, the test will start failing. |
1114 static const int kNumTestCases = 40; | 1138 static const int kNumTestCases = 40; |
1115 static const int kMaxFanOut = 3; | 1139 static const int kMaxFanOut = 3; |
1116 static const int kMaxArgs = 6; | 1140 static const int kMaxArgs = 6; |
1117 }; | 1141 }; |
1118 | 1142 |
1119 ErrorCode EqualityStressTestPolicy(Sandbox *sandbox, int sysno, void *aux) { | 1143 ErrorCode EqualityStressTestPolicy(Sandbox* sandbox, int sysno, void* aux) { |
1120 return reinterpret_cast<EqualityStressTest *>(aux)->Policy(sandbox, sysno); | 1144 return reinterpret_cast<EqualityStressTest*>(aux)->Policy(sandbox, sysno); |
1121 } | 1145 } |
1122 | 1146 |
1123 BPF_TEST(SandboxBpf, EqualityTests, EqualityStressTestPolicy, | 1147 BPF_TEST(SandboxBpf, |
| 1148 EqualityTests, |
| 1149 EqualityStressTestPolicy, |
1124 EqualityStressTest /* BPF_AUX */) { | 1150 EqualityStressTest /* BPF_AUX */) { |
1125 BPF_AUX.VerifyFilter(); | 1151 BPF_AUX.VerifyFilter(); |
1126 } | 1152 } |
1127 | 1153 |
1128 ErrorCode EqualityArgumentWidthPolicy(Sandbox *sandbox, int sysno, void *) { | 1154 ErrorCode EqualityArgumentWidthPolicy(Sandbox* sandbox, int sysno, void*) { |
1129 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1155 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
1130 // FIXME: we should really not have to do that in a trivial policy | 1156 // FIXME: we should really not have to do that in a trivial policy |
1131 return ErrorCode(ENOSYS); | 1157 return ErrorCode(ENOSYS); |
1132 } else if (sysno == __NR_uname) { | 1158 } else if (sysno == __NR_uname) { |
1133 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1159 return sandbox->Cond( |
1134 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1160 0, |
1135 0x55555555, ErrorCode(1), ErrorCode(2)), | 1161 ErrorCode::TP_32BIT, |
1136 // The BPF compiler and the BPF interpreter in the kernel are | 1162 ErrorCode::OP_EQUAL, |
1137 // (mostly) agnostic of the host platform's word size. The compiler | 1163 0, |
1138 // will happily generate code that tests a 64bit value, and the | 1164 sandbox->Cond(1, |
1139 // interpreter will happily perform this test. | 1165 ErrorCode::TP_32BIT, |
1140 // But unless there is a kernel bug, there is no way for us to pass | 1166 ErrorCode::OP_EQUAL, |
1141 // in a 64bit quantity on a 32bit platform. The upper 32bits should | 1167 0x55555555, |
1142 // always be zero. So, this test should always evaluate as false on | 1168 ErrorCode(1), |
1143 // 32bit systems. | 1169 ErrorCode(2)), |
1144 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_EQUAL, | 1170 // The BPF compiler and the BPF interpreter in the kernel are |
1145 0x55555555AAAAAAAAULL, ErrorCode(1), ErrorCode(2))); | 1171 // (mostly) agnostic of the host platform's word size. The compiler |
| 1172 // will happily generate code that tests a 64bit value, and the |
| 1173 // interpreter will happily perform this test. |
| 1174 // But unless there is a kernel bug, there is no way for us to pass |
| 1175 // in a 64bit quantity on a 32bit platform. The upper 32bits should |
| 1176 // always be zero. So, this test should always evaluate as false on |
| 1177 // 32bit systems. |
| 1178 sandbox->Cond(1, |
| 1179 ErrorCode::TP_64BIT, |
| 1180 ErrorCode::OP_EQUAL, |
| 1181 0x55555555AAAAAAAAULL, |
| 1182 ErrorCode(1), |
| 1183 ErrorCode(2))); |
1146 } else { | 1184 } else { |
1147 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1185 return ErrorCode(ErrorCode::ERR_ALLOWED); |
1148 } | 1186 } |
1149 } | 1187 } |
1150 | 1188 |
1151 BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { | 1189 BPF_TEST(SandboxBpf, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { |
1152 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); | 1190 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); |
1153 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); | 1191 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); |
1154 #if __SIZEOF_POINTER__ > 4 | 1192 #if __SIZEOF_POINTER__ > 4 |
1155 // On 32bit machines, there is no way to pass a 64bit argument through the | 1193 // On 32bit machines, there is no way to pass a 64bit argument through the |
1156 // syscall interface. So, we have to skip the part of the test that requires | 1194 // syscall interface. So, we have to skip the part of the test that requires |
1157 // 64bit arguments. | 1195 // 64bit arguments. |
1158 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); | 1196 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); |
1159 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); | 1197 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); |
1160 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); | 1198 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); |
1161 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); | 1199 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); |
1162 #else | 1200 #else |
1163 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); | 1201 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); |
1164 #endif | 1202 #endif |
1165 } | 1203 } |
1166 | 1204 |
1167 #if __SIZEOF_POINTER__ > 4 | 1205 #if __SIZEOF_POINTER__ > 4 |
1168 // On 32bit machines, there is no way to pass a 64bit argument through the | 1206 // On 32bit machines, there is no way to pass a 64bit argument through the |
1169 // syscall interface. So, we have to skip the part of the test that requires | 1207 // syscall interface. So, we have to skip the part of the test that requires |
1170 // 64bit arguments. | 1208 // 64bit arguments. |
1171 BPF_DEATH_TEST(SandboxBpf, EqualityArgumentUnallowed64bit, | 1209 BPF_DEATH_TEST(SandboxBpf, |
| 1210 EqualityArgumentUnallowed64bit, |
1172 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1211 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
1173 EqualityArgumentWidthPolicy) { | 1212 EqualityArgumentWidthPolicy) { |
1174 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); | 1213 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); |
1175 } | 1214 } |
1176 #endif | 1215 #endif |
1177 | 1216 |
1178 ErrorCode EqualityWithNegativeArgumentsPolicy(Sandbox *sandbox, int sysno, | 1217 ErrorCode EqualityWithNegativeArgumentsPolicy(Sandbox* sandbox, |
1179 void *) { | 1218 int sysno, |
| 1219 void*) { |
1180 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1220 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
1181 // FIXME: we should really not have to do that in a trivial policy | 1221 // FIXME: we should really not have to do that in a trivial policy |
1182 return ErrorCode(ENOSYS); | 1222 return ErrorCode(ENOSYS); |
1183 } else if (sysno == __NR_uname) { | 1223 } else if (sysno == __NR_uname) { |
1184 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1224 return sandbox->Cond(0, |
1185 0xFFFFFFFF, ErrorCode(1), ErrorCode(2)); | 1225 ErrorCode::TP_32BIT, |
| 1226 ErrorCode::OP_EQUAL, |
| 1227 0xFFFFFFFF, |
| 1228 ErrorCode(1), |
| 1229 ErrorCode(2)); |
1186 } else { | 1230 } else { |
1187 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1231 return ErrorCode(ErrorCode::ERR_ALLOWED); |
1188 } | 1232 } |
1189 } | 1233 } |
1190 | 1234 |
1191 BPF_TEST(SandboxBpf, EqualityWithNegativeArguments, | 1235 BPF_TEST(SandboxBpf, |
| 1236 EqualityWithNegativeArguments, |
1192 EqualityWithNegativeArgumentsPolicy) { | 1237 EqualityWithNegativeArgumentsPolicy) { |
1193 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); | 1238 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); |
1194 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); | 1239 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); |
1195 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); | 1240 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); |
1196 } | 1241 } |
1197 | 1242 |
1198 #if __SIZEOF_POINTER__ > 4 | 1243 #if __SIZEOF_POINTER__ > 4 |
1199 BPF_DEATH_TEST(SandboxBpf, EqualityWithNegative64bitArguments, | 1244 BPF_DEATH_TEST(SandboxBpf, |
| 1245 EqualityWithNegative64bitArguments, |
1200 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1246 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
1201 EqualityWithNegativeArgumentsPolicy) { | 1247 EqualityWithNegativeArgumentsPolicy) { |
1202 // When expecting a 32bit system call argument, we look at the MSB of the | 1248 // When expecting a 32bit system call argument, we look at the MSB of the |
1203 // 64bit value and allow both "0" and "-1". But the latter is allowed only | 1249 // 64bit value and allow both "0" and "-1". But the latter is allowed only |
1204 // iff the LSB was negative. So, this death test should error out. | 1250 // iff the LSB was negative. So, this death test should error out. |
1205 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); | 1251 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); |
1206 } | 1252 } |
1207 #endif | 1253 #endif |
1208 | |
1209 ErrorCode AllBitTestPolicy(Sandbox *sandbox, int sysno, void *) { | 1254 ErrorCode AllBitTestPolicy(Sandbox *sandbox, int sysno, void *) { |
1210 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of | 1255 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of |
1211 // different bitmasks. We try to find bitmasks that could conceivably | 1256 // different bitmasks. We try to find bitmasks that could conceivably |
1212 // touch corner cases. | 1257 // touch corner cases. |
1213 // For all of these tests, we override the uname(). We can make use with | 1258 // For all of these tests, we override the uname(). We can make use with |
1214 // a single system call number, as we use the first system call argument to | 1259 // a single system call number, as we use the first system call argument to |
1215 // select the different bit masks that we want to test against. | 1260 // select the different bit masks that we want to test against. |
1216 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1261 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
1217 // FIXME: we should really not have to do that in a trivial policy | 1262 // FIXME: we should really not have to do that in a trivial policy |
1218 return ErrorCode(ENOSYS); | 1263 return ErrorCode(ENOSYS); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1277 } | 1322 } |
1278 } | 1323 } |
1279 | 1324 |
1280 // Define a macro that performs tests using our test policy. | 1325 // Define a macro that performs tests using our test policy. |
1281 // NOTE: Not all of the arguments in this macro are actually used! | 1326 // NOTE: Not all of the arguments in this macro are actually used! |
1282 // They are here just to serve as documentation of the conditions | 1327 // They are here just to serve as documentation of the conditions |
1283 // implemented in the test policy. | 1328 // implemented in the test policy. |
1284 // Most notably, "op" and "mask" are unused by the macro. If you want | 1329 // Most notably, "op" and "mask" are unused by the macro. If you want |
1285 // to make changes to these values, you will have to edit the | 1330 // to make changes to these values, you will have to edit the |
1286 // test policy instead. | 1331 // test policy instead. |
1287 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ | 1332 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ |
1288 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) | 1333 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) |
1289 | 1334 |
1290 // Our uname() system call returns ErrorCode(1) for success and | 1335 // Our uname() system call returns ErrorCode(1) for success and |
1291 // ErrorCode(0) for failure. SandboxSyscall() turns this into an | 1336 // ErrorCode(0) for failure. SandboxSyscall() turns this into an |
1292 // exit code of -1 or 0. | 1337 // exit code of -1 or 0. |
1293 #define EXPECT_FAILURE 0 | 1338 #define EXPECT_FAILURE 0 |
1294 #define EXPECT_SUCCESS -1 | 1339 #define EXPECT_SUCCESS -1 |
1295 | 1340 |
1296 // A couple of our tests behave differently on 32bit and 64bit systems, as | 1341 // A couple of our tests behave differently on 32bit and 64bit systems, as |
1297 // there is no way for a 32bit system call to pass in a 64bit system call | 1342 // there is no way for a 32bit system call to pass in a 64bit system call |
1298 // argument "arg". | 1343 // argument "arg". |
1299 // We expect these tests to succeed on 64bit systems, but to tail on 32bit | 1344 // We expect these tests to succeed on 64bit systems, but to tail on 32bit |
1300 // systems. | 1345 // systems. |
1301 #define EXPT64_SUCCESS \ | 1346 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) |
1302 (sizeof(void *) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) | |
1303 | |
1304 BPF_TEST(SandboxBpf, AllBitTests, AllBitTestPolicy) { | 1347 BPF_TEST(SandboxBpf, AllBitTests, AllBitTestPolicy) { |
1305 // 32bit test: all of 0x0 (should always be true) | 1348 // 32bit test: all of 0x0 (should always be true) |
1306 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); | 1349 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); |
1307 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); | 1350 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); |
1308 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); | 1351 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); |
1309 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); | 1352 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); |
1310 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); | 1353 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); |
1311 | 1354 |
1312 // 32bit test: all of 0x1 | 1355 // 32bit test: all of 0x1 |
1313 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); | 1356 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1397 | 1440 |
1398 // 64bit test: all of 0x100000001 | 1441 // 64bit test: all of 0x100000001 |
1399 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1442 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1400 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1443 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1401 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1444 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1402 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1445 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
1403 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1446 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1404 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1447 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
1405 } | 1448 } |
1406 | 1449 |
1407 ErrorCode AnyBitTestPolicy(Sandbox *sandbox, int sysno, void *) { | 1450 ErrorCode AnyBitTestPolicy(Sandbox* sandbox, int sysno, void*) { |
1408 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of | 1451 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of |
1409 // different bitmasks. We try to find bitmasks that could conceivably | 1452 // different bitmasks. We try to find bitmasks that could conceivably |
1410 // touch corner cases. | 1453 // touch corner cases. |
1411 // For all of these tests, we override the uname(). We can make use with | 1454 // For all of these tests, we override the uname(). We can make use with |
1412 // a single system call number, as we use the first system call argument to | 1455 // a single system call number, as we use the first system call argument to |
1413 // select the different bit masks that we want to test against. | 1456 // select the different bit masks that we want to test against. |
1414 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1457 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
1415 // FIXME: we should really not have to do that in a trivial policy | 1458 // FIXME: we should really not have to do that in a trivial policy |
1416 return ErrorCode(ENOSYS); | 1459 return ErrorCode(ENOSYS); |
1417 } else if (sysno == __NR_uname) { | 1460 } else if (sysno == __NR_uname) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 | 1617 |
1575 // 64bit test: any of 0x100000001 | 1618 // 64bit test: any of 0x100000001 |
1576 BITMASK_TEST( 10, 0x000000000LL, ANYBITS64,0x100000001, EXPECT_FAILURE); | 1619 BITMASK_TEST( 10, 0x000000000LL, ANYBITS64,0x100000001, EXPECT_FAILURE); |
1577 BITMASK_TEST( 10, 0x000000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1620 BITMASK_TEST( 10, 0x000000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
1578 BITMASK_TEST( 10, 0x100000000LL, ANYBITS64,0x100000001, EXPT64_SUCCESS); | 1621 BITMASK_TEST( 10, 0x100000000LL, ANYBITS64,0x100000001, EXPT64_SUCCESS); |
1579 BITMASK_TEST( 10, 0x100000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1622 BITMASK_TEST( 10, 0x100000001LL, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
1580 BITMASK_TEST( 10, 0xFFFFFFFFU, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1623 BITMASK_TEST( 10, 0xFFFFFFFFU, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
1581 BITMASK_TEST( 10, -1L, ANYBITS64,0x100000001, EXPECT_SUCCESS); | 1624 BITMASK_TEST( 10, -1L, ANYBITS64,0x100000001, EXPECT_SUCCESS); |
1582 } | 1625 } |
1583 | 1626 |
1584 intptr_t PthreadTrapHandler(const struct arch_seccomp_data& args, void *aux) { | 1627 intptr_t PthreadTrapHandler(const struct arch_seccomp_data& args, void* aux) { |
1585 if (args.args[0] != (CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD)) { | 1628 if (args.args[0] != (CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD)) { |
1586 // We expect to get called for an attempt to fork(). No need to log that | 1629 // We expect to get called for an attempt to fork(). No need to log that |
1587 // call. But if we ever get called for anything else, we want to verbosely | 1630 // call. But if we ever get called for anything else, we want to verbosely |
1588 // print as much information as possible. | 1631 // print as much information as possible. |
1589 const char *msg = (const char *)aux; | 1632 const char* msg = (const char*)aux; |
1590 printf("Clone() was called with unexpected arguments\n" | 1633 printf( |
1591 " nr: %d\n" | 1634 "Clone() was called with unexpected arguments\n" |
1592 " 1: 0x%llX\n" | 1635 " nr: %d\n" |
1593 " 2: 0x%llX\n" | 1636 " 1: 0x%llX\n" |
1594 " 3: 0x%llX\n" | 1637 " 2: 0x%llX\n" |
1595 " 4: 0x%llX\n" | 1638 " 3: 0x%llX\n" |
1596 " 5: 0x%llX\n" | 1639 " 4: 0x%llX\n" |
1597 " 6: 0x%llX\n" | 1640 " 5: 0x%llX\n" |
1598 "%s\n", | 1641 " 6: 0x%llX\n" |
1599 args.nr, | 1642 "%s\n", |
1600 (long long)args.args[0], (long long)args.args[1], | 1643 args.nr, |
1601 (long long)args.args[2], (long long)args.args[3], | 1644 (long long)args.args[0], |
1602 (long long)args.args[4], (long long)args.args[5], | 1645 (long long)args.args[1], |
1603 msg); | 1646 (long long)args.args[2], |
| 1647 (long long)args.args[3], |
| 1648 (long long)args.args[4], |
| 1649 (long long)args.args[5], |
| 1650 msg); |
1604 } | 1651 } |
1605 return -EPERM; | 1652 return -EPERM; |
1606 } | 1653 } |
1607 | 1654 ErrorCode PthreadPolicyEquality(Sandbox* sandbox, int sysno, void* aux) { |
1608 ErrorCode PthreadPolicyEquality(Sandbox *sandbox, int sysno, void *aux) { | |
1609 // This policy allows creating threads with pthread_create(). But it | 1655 // This policy allows creating threads with pthread_create(). But it |
1610 // doesn't allow any other uses of clone(). Most notably, it does not | 1656 // doesn't allow any other uses of clone(). Most notably, it does not |
1611 // allow callers to implement fork() or vfork() by passing suitable flags | 1657 // allow callers to implement fork() or vfork() by passing suitable flags |
1612 // to the clone() system call. | 1658 // to the clone() system call. |
1613 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1659 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
1614 // FIXME: we should really not have to do that in a trivial policy | 1660 // FIXME: we should really not have to do that in a trivial policy |
1615 return ErrorCode(ENOSYS); | 1661 return ErrorCode(ENOSYS); |
1616 } else if (sysno == __NR_clone) { | 1662 } else if (sysno == __NR_clone) { |
1617 // We have seen two different valid combinations of flags. Glibc | 1663 // We have seen two different valid combinations of flags. Glibc |
1618 // uses the more modern flags, sets the TLS from the call to clone(), and | 1664 // uses the more modern flags, sets the TLS from the call to clone(), and |
(...skipping 19 matching lines...) Expand all Loading... |
1638 ErrorCode(ErrorCode::ERR_ALLOWED), | 1684 ErrorCode(ErrorCode::ERR_ALLOWED), |
1639 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1685 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
1640 kBaseAndroidCloneMask, | 1686 kBaseAndroidCloneMask, |
1641 ErrorCode(ErrorCode::ERR_ALLOWED), | 1687 ErrorCode(ErrorCode::ERR_ALLOWED), |
1642 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); | 1688 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); |
1643 } else { | 1689 } else { |
1644 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1690 return ErrorCode(ErrorCode::ERR_ALLOWED); |
1645 } | 1691 } |
1646 } | 1692 } |
1647 | 1693 |
1648 ErrorCode PthreadPolicyBitMask(Sandbox *sandbox, int sysno, void *aux) { | 1694 ErrorCode PthreadPolicyBitMask(Sandbox* sandbox, int sysno, void* aux) { |
1649 // This policy allows creating threads with pthread_create(). But it | 1695 // This policy allows creating threads with pthread_create(). But it |
1650 // doesn't allow any other uses of clone(). Most notably, it does not | 1696 // doesn't allow any other uses of clone(). Most notably, it does not |
1651 // allow callers to implement fork() or vfork() by passing suitable flags | 1697 // allow callers to implement fork() or vfork() by passing suitable flags |
1652 // to the clone() system call. | 1698 // to the clone() system call. |
1653 if (!Sandbox::IsValidSyscallNumber(sysno)) { | 1699 if (!Sandbox::IsValidSyscallNumber(sysno)) { |
1654 // FIXME: we should really not have to do that in a trivial policy | 1700 // FIXME: we should really not have to do that in a trivial policy |
1655 return ErrorCode(ENOSYS); | 1701 return ErrorCode(ENOSYS); |
1656 } else if (sysno == __NR_clone) { | 1702 } else if (sysno == __NR_clone) { |
1657 // We have seen two different valid combinations of flags. Glibc | 1703 // We have seen two different valid combinations of flags. Glibc |
1658 // uses the more modern flags, sets the TLS from the call to clone(), and | 1704 // uses the more modern flags, sets the TLS from the call to clone(), and |
(...skipping 24 matching lines...) Expand all Loading... |
1683 " and futex bits in call to clone()"), | 1729 " and futex bits in call to clone()"), |
1684 ErrorCode(ErrorCode::ERR_ALLOWED))), | 1730 ErrorCode(ErrorCode::ERR_ALLOWED))), |
1685 sandbox->Trap(PthreadTrapHandler, | 1731 sandbox->Trap(PthreadTrapHandler, |
1686 "Missing mandatory CLONE_XXX flags " | 1732 "Missing mandatory CLONE_XXX flags " |
1687 "when creating new thread"))); | 1733 "when creating new thread"))); |
1688 } else { | 1734 } else { |
1689 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1735 return ErrorCode(ErrorCode::ERR_ALLOWED); |
1690 } | 1736 } |
1691 } | 1737 } |
1692 | 1738 |
1693 static void *ThreadFnc(void *arg) { | 1739 static void* ThreadFnc(void* arg) { |
1694 ++*reinterpret_cast<int *>(arg); | 1740 ++*reinterpret_cast<int*>(arg); |
1695 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); | 1741 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); |
1696 return NULL; | 1742 return NULL; |
1697 } | 1743 } |
1698 | 1744 |
1699 static void PthreadTest() { | 1745 static void PthreadTest() { |
1700 // Attempt to start a joinable thread. This should succeed. | 1746 // Attempt to start a joinable thread. This should succeed. |
1701 pthread_t thread; | 1747 pthread_t thread; |
1702 int thread_ran = 0; | 1748 int thread_ran = 0; |
1703 BPF_ASSERT(!pthread_create(&thread, NULL, ThreadFnc, &thread_ran)); | 1749 BPF_ASSERT(!pthread_create(&thread, NULL, ThreadFnc, &thread_ran)); |
1704 BPF_ASSERT(!pthread_join(thread, NULL)); | 1750 BPF_ASSERT(!pthread_join(thread, NULL)); |
1705 BPF_ASSERT(thread_ran); | 1751 BPF_ASSERT(thread_ran); |
1706 | 1752 |
1707 // Attempt to start a detached thread. This should succeed. | 1753 // Attempt to start a detached thread. This should succeed. |
1708 thread_ran = 0; | 1754 thread_ran = 0; |
1709 pthread_attr_t attr; | 1755 pthread_attr_t attr; |
1710 BPF_ASSERT(!pthread_attr_init(&attr)); | 1756 BPF_ASSERT(!pthread_attr_init(&attr)); |
1711 BPF_ASSERT(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); | 1757 BPF_ASSERT(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); |
1712 BPF_ASSERT(!pthread_create(&thread, &attr, ThreadFnc, &thread_ran)); | 1758 BPF_ASSERT(!pthread_create(&thread, &attr, ThreadFnc, &thread_ran)); |
1713 BPF_ASSERT(!pthread_attr_destroy(&attr)); | 1759 BPF_ASSERT(!pthread_attr_destroy(&attr)); |
1714 while (SandboxSyscall(__NR_futex, &thread_ran, FUTEX_WAIT, | 1760 while (SandboxSyscall(__NR_futex, &thread_ran, FUTEX_WAIT, 0, 0, 0, 0) == |
1715 0, 0, 0, 0) == -EINTR) { | 1761 -EINTR) { |
1716 } | 1762 } |
1717 BPF_ASSERT(thread_ran); | 1763 BPF_ASSERT(thread_ran); |
1718 | 1764 |
1719 // Attempt to fork() a process using clone(). This should fail. We use the | 1765 // Attempt to fork() a process using clone(). This should fail. We use the |
1720 // same flags that glibc uses when calling fork(). But we don't actually | 1766 // same flags that glibc uses when calling fork(). But we don't actually |
1721 // try calling the fork() implementation in the C run-time library, as | 1767 // try calling the fork() implementation in the C run-time library, as |
1722 // run-time libraries other than glibc might call __NR_fork instead of | 1768 // run-time libraries other than glibc might call __NR_fork instead of |
1723 // __NR_clone, and that would introduce a bogus test failure. | 1769 // __NR_clone, and that would introduce a bogus test failure. |
1724 int pid; | 1770 int pid; |
1725 BPF_ASSERT(SandboxSyscall(__NR_clone, | 1771 BPF_ASSERT(SandboxSyscall(__NR_clone, |
1726 CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, | 1772 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, |
1727 0, 0, &pid) == -EPERM); | 1773 0, |
| 1774 0, |
| 1775 &pid) == -EPERM); |
1728 } | 1776 } |
1729 | 1777 |
1730 BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) { | 1778 BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); } |
1731 PthreadTest(); | |
1732 } | |
1733 | 1779 |
1734 BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) { | 1780 BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); } |
1735 PthreadTest(); | |
1736 } | |
1737 | 1781 |
1738 } // namespace | 1782 } // namespace |
OLD | NEW |