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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 BPF_ASSERT_EQ(2, pid); | 117 BPF_ASSERT_EQ(2, pid); |
118 | 118 |
119 // N.B.: Any future call to getpid() would corrupt the stack. | 119 // N.B.: Any future call to getpid() would corrupt the stack. |
120 // This is OK. The SANDBOX_TEST() macro is guaranteed to | 120 // This is OK. The SANDBOX_TEST() macro is guaranteed to |
121 // only ever call _exit() after the test completes. | 121 // only ever call _exit() after the test completes. |
122 } | 122 } |
123 } | 123 } |
124 | 124 |
125 // A simple blacklist test | 125 // A simple blacklist test |
126 | 126 |
127 ErrorCode BlacklistNanosleepPolicy(SandboxBPF*, int sysno, void* aux) { | 127 class BlacklistNanosleepPolicy : public SandboxBPFPolicy { |
128 // Since no type was specified in BPF_TEST as a fourth argument, | 128 public: |
129 // |aux| must be NULL here. | 129 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
130 BPF_ASSERT(NULL == aux); | 130 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
131 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 131 switch (sysno) { |
132 // FIXME: we should really not have to do that in a trivial policy | 132 case __NR_nanosleep: |
133 return ErrorCode(ENOSYS); | 133 return ErrorCode(EACCES); |
134 default: | |
135 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
136 } | |
134 } | 137 } |
jln (very slow on Chromium)
2014/05/19 21:22:21
It would be fine in C++11 to punt on DISALLOW_COPY
| |
138 }; | |
135 | 139 |
136 switch (sysno) { | 140 BPF_TEST_C(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { |
137 case __NR_nanosleep: | |
138 return ErrorCode(EACCES); | |
139 default: | |
140 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
141 } | |
142 } | |
143 | |
144 BPF_TEST(SandboxBPF, ApplyBasicBlacklistPolicy, BlacklistNanosleepPolicy) { | |
145 // nanosleep() should be denied | 141 // nanosleep() should be denied |
146 const struct timespec ts = {0, 0}; | 142 const struct timespec ts = {0, 0}; |
147 errno = 0; | 143 errno = 0; |
148 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 144 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
149 BPF_ASSERT(errno == EACCES); | 145 BPF_ASSERT(errno == EACCES); |
150 } | 146 } |
147 | |
151 // Now do a simple whitelist test | 148 // Now do a simple whitelist test |
152 | 149 |
153 ErrorCode WhitelistGetpidPolicy(SandboxBPF*, int sysno, void*) { | 150 class WhitelistGetpidPolicy : public SandboxBPFPolicy { |
154 switch (sysno) { | 151 public: |
155 case __NR_getpid: | 152 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
156 case __NR_exit_group: | 153 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
157 return ErrorCode(ErrorCode::ERR_ALLOWED); | 154 switch (sysno) { |
158 default: | 155 case __NR_getpid: |
159 return ErrorCode(ENOMEM); | 156 case __NR_exit_group: |
157 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
158 default: | |
159 return ErrorCode(ENOMEM); | |
160 } | |
160 } | 161 } |
161 } | 162 }; |
162 | 163 |
163 BPF_TEST(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { | 164 BPF_TEST_C(SandboxBPF, ApplyBasicWhitelistPolicy, WhitelistGetpidPolicy) { |
164 // getpid() should be allowed | 165 // getpid() should be allowed |
165 errno = 0; | 166 errno = 0; |
166 BPF_ASSERT(syscall(__NR_getpid) > 0); | 167 BPF_ASSERT(syscall(__NR_getpid) > 0); |
167 BPF_ASSERT(errno == 0); | 168 BPF_ASSERT(errno == 0); |
168 | 169 |
169 // getpgid() should be denied | 170 // getpgid() should be denied |
170 BPF_ASSERT(getpgid(0) == -1); | 171 BPF_ASSERT(getpgid(0) == -1); |
171 BPF_ASSERT(errno == ENOMEM); | 172 BPF_ASSERT(errno == ENOMEM); |
172 } | 173 } |
173 | 174 |
174 // A simple blacklist policy, with a SIGSYS handler | 175 // A simple blacklist policy, with a SIGSYS handler |
175 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { | 176 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) { |
176 // We also check that the auxiliary data is correct | 177 // We also check that the auxiliary data is correct |
177 SANDBOX_ASSERT(aux); | 178 SANDBOX_ASSERT(aux); |
178 *(static_cast<int*>(aux)) = kExpectedReturnValue; | 179 *(static_cast<int*>(aux)) = kExpectedReturnValue; |
179 return -ENOMEM; | 180 return -ENOMEM; |
180 } | 181 } |
181 | 182 |
182 ErrorCode BlacklistNanosleepPolicySigsys(SandboxBPF* sandbox, | 183 ErrorCode BlacklistNanosleepPolicySigsys(SandboxBPF* sandbox, |
183 int sysno, | 184 int sysno, |
184 int* aux) { | 185 int* aux) { |
185 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 186 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
186 // FIXME: we should really not have to do that in a trivial policy | |
187 return ErrorCode(ENOSYS); | |
188 } | |
189 | |
190 switch (sysno) { | 187 switch (sysno) { |
191 case __NR_nanosleep: | 188 case __NR_nanosleep: |
192 return sandbox->Trap(EnomemHandler, aux); | 189 return sandbox->Trap(EnomemHandler, aux); |
193 default: | 190 default: |
194 return ErrorCode(ErrorCode::ERR_ALLOWED); | 191 return ErrorCode(ErrorCode::ERR_ALLOWED); |
195 } | 192 } |
196 } | 193 } |
197 | 194 |
198 BPF_TEST(SandboxBPF, | 195 BPF_TEST(SandboxBPF, |
199 BasicBlacklistWithSigsys, | 196 BasicBlacklistWithSigsys, |
200 BlacklistNanosleepPolicySigsys, | 197 BlacklistNanosleepPolicySigsys, |
201 int /* (*BPF_AUX) */) { | 198 int /* (*BPF_AUX) */) { |
202 // getpid() should work properly | 199 // getpid() should work properly |
203 errno = 0; | 200 errno = 0; |
204 BPF_ASSERT(syscall(__NR_getpid) > 0); | 201 BPF_ASSERT(syscall(__NR_getpid) > 0); |
205 BPF_ASSERT(errno == 0); | 202 BPF_ASSERT(errno == 0); |
206 | 203 |
207 // Our Auxiliary Data, should be reset by the signal handler | 204 // Our Auxiliary Data, should be reset by the signal handler |
208 *BPF_AUX = -1; | 205 *BPF_AUX = -1; |
209 const struct timespec ts = {0, 0}; | 206 const struct timespec ts = {0, 0}; |
210 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); | 207 BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1); |
211 BPF_ASSERT(errno == ENOMEM); | 208 BPF_ASSERT(errno == ENOMEM); |
212 | 209 |
213 // We expect the signal handler to modify AuxData | 210 // We expect the signal handler to modify AuxData |
214 BPF_ASSERT(*BPF_AUX == kExpectedReturnValue); | 211 BPF_ASSERT(*BPF_AUX == kExpectedReturnValue); |
215 } | 212 } |
216 | 213 |
217 // A simple test that verifies we can return arbitrary errno values. | 214 // A simple test that verifies we can return arbitrary errno values. |
218 | 215 |
219 ErrorCode ErrnoTestPolicy(SandboxBPF*, int sysno, void*) { | 216 class ErrnoTestPolicy : public SandboxBPFPolicy { |
220 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 217 public: |
221 // FIXME: we should really not have to do that in a trivial policy | 218 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE; |
222 return ErrorCode(ENOSYS); | 219 }; |
223 } | |
224 | 220 |
221 ErrorCode ErrnoTestPolicy::EvaluateSyscall(SandboxBPF*, int sysno) const { | |
222 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
225 switch (sysno) { | 223 switch (sysno) { |
226 #if defined(ANDROID) | 224 #if defined(ANDROID) |
227 case __NR_dup3: // dup2 is a wrapper of dup3 in android | 225 case __NR_dup3: // dup2 is a wrapper of dup3 in android |
228 #else | 226 #else |
229 case __NR_dup2: | 227 case __NR_dup2: |
230 #endif | 228 #endif |
231 // Pretend that dup2() worked, but don't actually do anything. | 229 // Pretend that dup2() worked, but don't actually do anything. |
232 return ErrorCode(0); | 230 return ErrorCode(0); |
233 case __NR_setuid: | 231 case __NR_setuid: |
234 #if defined(__NR_setuid32) | 232 #if defined(__NR_setuid32) |
235 case __NR_setuid32: | 233 case __NR_setuid32: |
236 #endif | 234 #endif |
237 // Return errno = 1. | 235 // Return errno = 1. |
238 return ErrorCode(1); | 236 return ErrorCode(1); |
239 case __NR_setgid: | 237 case __NR_setgid: |
240 #if defined(__NR_setgid32) | 238 #if defined(__NR_setgid32) |
241 case __NR_setgid32: | 239 case __NR_setgid32: |
242 #endif | 240 #endif |
243 // Return maximum errno value (typically 4095). | 241 // Return maximum errno value (typically 4095). |
244 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); | 242 return ErrorCode(ErrorCode::ERR_MAX_ERRNO); |
245 case __NR_uname: | 243 case __NR_uname: |
246 // Return errno = 42; | 244 // Return errno = 42; |
247 return ErrorCode(42); | 245 return ErrorCode(42); |
248 default: | 246 default: |
249 return ErrorCode(ErrorCode::ERR_ALLOWED); | 247 return ErrorCode(ErrorCode::ERR_ALLOWED); |
250 } | 248 } |
251 } | 249 } |
252 | 250 |
253 BPF_TEST(SandboxBPF, ErrnoTest, ErrnoTestPolicy) { | 251 BPF_TEST_C(SandboxBPF, ErrnoTest, ErrnoTestPolicy) { |
254 // Verify that dup2() returns success, but doesn't actually run. | 252 // Verify that dup2() returns success, but doesn't actually run. |
255 int fds[4]; | 253 int fds[4]; |
256 BPF_ASSERT(pipe(fds) == 0); | 254 BPF_ASSERT(pipe(fds) == 0); |
257 BPF_ASSERT(pipe(fds + 2) == 0); | 255 BPF_ASSERT(pipe(fds + 2) == 0); |
258 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); | 256 BPF_ASSERT(dup2(fds[2], fds[0]) == 0); |
259 char buf[1] = {}; | 257 char buf[1] = {}; |
260 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); | 258 BPF_ASSERT(write(fds[1], "\x55", 1) == 1); |
261 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); | 259 BPF_ASSERT(write(fds[3], "\xAA", 1) == 1); |
262 BPF_ASSERT(read(fds[0], buf, 1) == 1); | 260 BPF_ASSERT(read(fds[0], buf, 1) == 1); |
263 | 261 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 // We try to make sure we exercise optimizations in the BPF compiler. We make | 358 // We try to make sure we exercise optimizations in the BPF compiler. We make |
361 // sure that the compiler can have an opportunity to coalesce syscalls with | 359 // sure that the compiler can have an opportunity to coalesce syscalls with |
362 // contiguous numbers and we also make sure that disjoint sets can return the | 360 // contiguous numbers and we also make sure that disjoint sets can return the |
363 // same errno. | 361 // same errno. |
364 int SysnoToRandomErrno(int sysno) { | 362 int SysnoToRandomErrno(int sysno) { |
365 // Small contiguous sets of 3 system calls return an errno equal to the | 363 // Small contiguous sets of 3 system calls return an errno equal to the |
366 // index of that set + 1 (so that we never return a NUL errno). | 364 // index of that set + 1 (so that we never return a NUL errno). |
367 return ((sysno & ~3) >> 2) % 29 + 1; | 365 return ((sysno & ~3) >> 2) % 29 + 1; |
368 } | 366 } |
369 | 367 |
370 ErrorCode SyntheticPolicy(SandboxBPF*, int sysno, void*) { | 368 class SyntheticPolicy : public SandboxBPFPolicy { |
371 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 369 public: |
372 // FIXME: we should really not have to do that in a trivial policy | 370 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
373 return ErrorCode(ENOSYS); | 371 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
374 } | 372 if (sysno == __NR_exit_group || sysno == __NR_write) { |
375 | 373 // exit_group() is special, we really need it to work. |
376 if (sysno == __NR_exit_group || sysno == __NR_write) { | 374 // write() is needed for BPF_ASSERT() to report a useful error message. |
377 // exit_group() is special, we really need it to work. | 375 return ErrorCode(ErrorCode::ERR_ALLOWED); |
378 // write() is needed for BPF_ASSERT() to report a useful error message. | 376 } |
379 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
380 } else { | |
381 return ErrorCode(SysnoToRandomErrno(sysno)); | 377 return ErrorCode(SysnoToRandomErrno(sysno)); |
382 } | 378 } |
383 } | 379 }; |
384 | 380 |
385 BPF_TEST(SandboxBPF, SyntheticPolicy, SyntheticPolicy) { | 381 BPF_TEST_C(SandboxBPF, SyntheticPolicy, SyntheticPolicy) { |
386 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int | 382 // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int |
387 // overflow. | 383 // overflow. |
388 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= | 384 BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >= |
389 static_cast<int>(MAX_PUBLIC_SYSCALL)); | 385 static_cast<int>(MAX_PUBLIC_SYSCALL)); |
390 | 386 |
391 for (int syscall_number = static_cast<int>(MIN_SYSCALL); | 387 for (int syscall_number = static_cast<int>(MIN_SYSCALL); |
392 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); | 388 syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL); |
393 ++syscall_number) { | 389 ++syscall_number) { |
394 if (syscall_number == __NR_exit_group || syscall_number == __NR_write) { | 390 if (syscall_number == __NR_exit_group || syscall_number == __NR_write) { |
395 // exit_group() is special | 391 // exit_group() is special |
(...skipping 13 matching lines...) Expand all Loading... | |
409 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). | 405 // MIN_PRIVATE_SYSCALL plus 1 (to avoid NUL errno). |
410 int ArmPrivateSysnoToErrno(int sysno) { | 406 int ArmPrivateSysnoToErrno(int sysno) { |
411 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && | 407 if (sysno >= static_cast<int>(MIN_PRIVATE_SYSCALL) && |
412 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 408 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
413 return (sysno - MIN_PRIVATE_SYSCALL) + 1; | 409 return (sysno - MIN_PRIVATE_SYSCALL) + 1; |
414 } else { | 410 } else { |
415 return ENOSYS; | 411 return ENOSYS; |
416 } | 412 } |
417 } | 413 } |
418 | 414 |
419 ErrorCode ArmPrivatePolicy(SandboxBPF*, int sysno, void*) { | 415 class ArmPrivatePolicy : public SandboxBPFPolicy { |
420 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 416 public: |
421 // FIXME: we should really not have to do that in a trivial policy. | 417 virtual ErrorCode EvaluateSyscall(SandboxBPF*, int sysno) const OVERRIDE { |
422 return ErrorCode(ENOSYS); | 418 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
423 } | 419 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual |
424 | 420 // ARM private system calls. |
425 // Start from |__ARM_NR_set_tls + 1| so as not to mess with actual | 421 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && |
426 // ARM private system calls. | 422 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { |
427 if (sysno >= static_cast<int>(__ARM_NR_set_tls + 1) && | 423 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); |
428 sysno <= static_cast<int>(MAX_PRIVATE_SYSCALL)) { | 424 } |
429 return ErrorCode(ArmPrivateSysnoToErrno(sysno)); | |
430 } else { | |
431 return ErrorCode(ErrorCode::ERR_ALLOWED); | 425 return ErrorCode(ErrorCode::ERR_ALLOWED); |
432 } | 426 } |
433 } | 427 }; |
434 | 428 |
435 BPF_TEST(SandboxBPF, ArmPrivatePolicy, ArmPrivatePolicy) { | 429 BPF_TEST_C(SandboxBPF, ArmPrivatePolicy, ArmPrivatePolicy) { |
436 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); | 430 for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1); |
437 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); | 431 syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL); |
438 ++syscall_number) { | 432 ++syscall_number) { |
439 errno = 0; | 433 errno = 0; |
440 BPF_ASSERT(syscall(syscall_number) == -1); | 434 BPF_ASSERT(syscall(syscall_number) == -1); |
441 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); | 435 BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number)); |
442 } | 436 } |
443 } | 437 } |
444 #endif // defined(__arm__) | 438 #endif // defined(__arm__) |
445 | 439 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
522 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { | 516 intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) { |
523 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { | 517 if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) { |
524 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always | 518 // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always |
525 // return an error. But our handler allows this call. | 519 // return an error. But our handler allows this call. |
526 return 0; | 520 return 0; |
527 } else { | 521 } else { |
528 return SandboxBPF::ForwardSyscall(args); | 522 return SandboxBPF::ForwardSyscall(args); |
529 } | 523 } |
530 } | 524 } |
531 | 525 |
532 ErrorCode PrctlPolicy(SandboxBPF* sandbox, int sysno, void* aux) { | 526 class PrctlPolicy : public SandboxBPFPolicy { |
533 setenv(kSandboxDebuggingEnv, "t", 0); | 527 public: |
534 Die::SuppressInfoMessages(true); | 528 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
529 int sysno) const OVERRIDE { | |
530 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
531 setenv(kSandboxDebuggingEnv, "t", 0); | |
532 Die::SuppressInfoMessages(true); | |
535 | 533 |
536 if (sysno == __NR_prctl) { | 534 if (sysno == __NR_prctl) { |
537 // Handle prctl() inside an UnsafeTrap() | 535 // Handle prctl() inside an UnsafeTrap() |
538 return sandbox->UnsafeTrap(PrctlHandler, NULL); | 536 return sandbox->UnsafeTrap(PrctlHandler, NULL); |
539 } else if (SandboxBPF::IsValidSyscallNumber(sysno)) { | 537 } |
538 | |
540 // Allow all other system calls. | 539 // Allow all other system calls. |
541 return ErrorCode(ErrorCode::ERR_ALLOWED); | 540 return ErrorCode(ErrorCode::ERR_ALLOWED); |
542 } else { | |
543 return ErrorCode(ENOSYS); | |
544 } | 541 } |
545 } | 542 }; |
546 | 543 |
547 BPF_TEST(SandboxBPF, ForwardSyscall, PrctlPolicy) { | 544 BPF_TEST_C(SandboxBPF, ForwardSyscall, PrctlPolicy) { |
548 // This call should never be allowed. But our policy will intercept it and | 545 // This call should never be allowed. But our policy will intercept it and |
549 // let it pass successfully. | 546 // let it pass successfully. |
550 BPF_ASSERT( | 547 BPF_ASSERT( |
551 !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL)); | 548 !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL)); |
552 | 549 |
553 // Verify that the call will fail, if it makes it all the way to the kernel. | 550 // Verify that the call will fail, if it makes it all the way to the kernel. |
554 BPF_ASSERT( | 551 BPF_ASSERT( |
555 prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1); | 552 prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1); |
556 | 553 |
557 // And verify that other uses of prctl() work just fine. | 554 // And verify that other uses of prctl() work just fine. |
(...skipping 10 matching lines...) Expand all Loading... | |
568 // unaffected by our policy. | 565 // unaffected by our policy. |
569 struct utsname uts = {}; | 566 struct utsname uts = {}; |
570 BPF_ASSERT(!uname(&uts)); | 567 BPF_ASSERT(!uname(&uts)); |
571 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); | 568 BPF_ASSERT(!strcmp(uts.sysname, "Linux")); |
572 } | 569 } |
573 | 570 |
574 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { | 571 intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) { |
575 return SandboxBPF::ForwardSyscall(args); | 572 return SandboxBPF::ForwardSyscall(args); |
576 } | 573 } |
577 | 574 |
578 ErrorCode RedirectAllSyscallsPolicy(SandboxBPF* sandbox, int sysno, void* aux) { | 575 class RedirectAllSyscallsPolicy : public SandboxBPFPolicy { |
576 public: | |
577 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | |
578 int sysno) const OVERRIDE; | |
579 }; | |
580 | |
581 ErrorCode RedirectAllSyscallsPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
582 int sysno) const { | |
583 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
579 setenv(kSandboxDebuggingEnv, "t", 0); | 584 setenv(kSandboxDebuggingEnv, "t", 0); |
580 Die::SuppressInfoMessages(true); | 585 Die::SuppressInfoMessages(true); |
581 | 586 |
582 // Some system calls must always be allowed, if our policy wants to make | 587 // Some system calls must always be allowed, if our policy wants to make |
583 // use of UnsafeTrap() | 588 // use of UnsafeTrap() |
584 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn | 589 if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn |
585 #if defined(__NR_sigprocmask) | 590 #if defined(__NR_sigprocmask) |
586 || | 591 || |
587 sysno == __NR_sigprocmask | 592 sysno == __NR_sigprocmask |
588 #endif | 593 #endif |
589 #if defined(__NR_sigreturn) | 594 #if defined(__NR_sigreturn) |
590 || | 595 || |
591 sysno == __NR_sigreturn | 596 sysno == __NR_sigreturn |
592 #endif | 597 #endif |
593 ) { | 598 ) { |
594 return ErrorCode(ErrorCode::ERR_ALLOWED); | 599 return ErrorCode(ErrorCode::ERR_ALLOWED); |
595 } else if (SandboxBPF::IsValidSyscallNumber(sysno)) { | |
596 return sandbox->UnsafeTrap(AllowRedirectedSyscall, aux); | |
597 } else { | |
598 return ErrorCode(ENOSYS); | |
599 } | 600 } |
601 return sandbox->UnsafeTrap(AllowRedirectedSyscall, NULL); | |
600 } | 602 } |
601 | 603 |
602 int bus_handler_fd_ = -1; | 604 int bus_handler_fd_ = -1; |
603 | 605 |
604 void SigBusHandler(int, siginfo_t* info, void* void_context) { | 606 void SigBusHandler(int, siginfo_t* info, void* void_context) { |
605 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); | 607 BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1); |
606 } | 608 } |
607 | 609 |
608 BPF_TEST(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) { | 610 BPF_TEST_C(SandboxBPF, SigBus, RedirectAllSyscallsPolicy) { |
609 // We use the SIGBUS bit in the signal mask as a thread-local boolean | 611 // We use the SIGBUS bit in the signal mask as a thread-local boolean |
610 // value in the implementation of UnsafeTrap(). This is obviously a bit | 612 // value in the implementation of UnsafeTrap(). This is obviously a bit |
611 // of a hack that could conceivably interfere with code that uses SIGBUS | 613 // of a hack that could conceivably interfere with code that uses SIGBUS |
612 // in more traditional ways. This test verifies that basic functionality | 614 // in more traditional ways. This test verifies that basic functionality |
613 // of SIGBUS is not impacted, but it is certainly possibly to construe | 615 // of SIGBUS is not impacted, but it is certainly possibly to construe |
614 // more complex uses of signals where our use of the SIGBUS mask is not | 616 // more complex uses of signals where our use of the SIGBUS mask is not |
615 // 100% transparent. This is expected behavior. | 617 // 100% transparent. This is expected behavior. |
616 int fds[2]; | 618 int fds[2]; |
617 BPF_ASSERT(pipe(fds) == 0); | 619 BPF_ASSERT(pipe(fds) == 0); |
618 bus_handler_fd_ = fds[1]; | 620 bus_handler_fd_ = fds[1]; |
619 struct sigaction sa = {}; | 621 struct sigaction sa = {}; |
620 sa.sa_sigaction = SigBusHandler; | 622 sa.sa_sigaction = SigBusHandler; |
621 sa.sa_flags = SA_SIGINFO; | 623 sa.sa_flags = SA_SIGINFO; |
622 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); | 624 BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0); |
623 raise(SIGBUS); | 625 raise(SIGBUS); |
624 char c = '\000'; | 626 char c = '\000'; |
625 BPF_ASSERT(read(fds[0], &c, 1) == 1); | 627 BPF_ASSERT(read(fds[0], &c, 1) == 1); |
626 BPF_ASSERT(close(fds[0]) == 0); | 628 BPF_ASSERT(close(fds[0]) == 0); |
627 BPF_ASSERT(close(fds[1]) == 0); | 629 BPF_ASSERT(close(fds[1]) == 0); |
628 BPF_ASSERT(c == 0x55); | 630 BPF_ASSERT(c == 0x55); |
629 } | 631 } |
630 | 632 |
631 BPF_TEST(SandboxBPF, SigMask, RedirectAllSyscallsPolicy) { | 633 BPF_TEST_C(SandboxBPF, SigMask, RedirectAllSyscallsPolicy) { |
632 // Signal masks are potentially tricky to handle. For instance, if we | 634 // Signal masks are potentially tricky to handle. For instance, if we |
633 // ever tried to update them from inside a Trap() or UnsafeTrap() handler, | 635 // ever tried to update them from inside a Trap() or UnsafeTrap() handler, |
634 // the call to sigreturn() at the end of the signal handler would undo | 636 // the call to sigreturn() at the end of the signal handler would undo |
635 // all of our efforts. So, it makes sense to test that sigprocmask() | 637 // all of our efforts. So, it makes sense to test that sigprocmask() |
636 // works, even if we have a policy in place that makes use of UnsafeTrap(). | 638 // works, even if we have a policy in place that makes use of UnsafeTrap(). |
637 // In practice, this works because we force sigprocmask() to be handled | 639 // In practice, this works because we force sigprocmask() to be handled |
638 // entirely in the kernel. | 640 // entirely in the kernel. |
639 sigset_t mask0, mask1, mask2; | 641 sigset_t mask0, mask1, mask2; |
640 | 642 |
641 // Call sigprocmask() to verify that SIGUSR2 wasn't blocked, if we didn't | 643 // Call sigprocmask() to verify that SIGUSR2 wasn't blocked, if we didn't |
642 // change the mask (it shouldn't have been, as it isn't blocked by default | 644 // change the mask (it shouldn't have been, as it isn't blocked by default |
643 // in POSIX). | 645 // in POSIX). |
644 // | 646 // |
645 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. | 647 // Use SIGUSR2 because Android seems to use SIGUSR1 for some purpose. |
646 sigemptyset(&mask0); | 648 sigemptyset(&mask0); |
647 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); | 649 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1)); |
648 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); | 650 BPF_ASSERT(!sigismember(&mask1, SIGUSR2)); |
649 | 651 |
650 // Try again, and this time we verify that we can block it. This | 652 // Try again, and this time we verify that we can block it. This |
651 // requires a second call to sigprocmask(). | 653 // requires a second call to sigprocmask(). |
652 sigaddset(&mask0, SIGUSR2); | 654 sigaddset(&mask0, SIGUSR2); |
653 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); | 655 BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL)); |
654 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); | 656 BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2)); |
655 BPF_ASSERT(sigismember(&mask2, SIGUSR2)); | 657 BPF_ASSERT(sigismember(&mask2, SIGUSR2)); |
656 } | 658 } |
657 | 659 |
658 BPF_TEST(SandboxBPF, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { | 660 BPF_TEST_C(SandboxBPF, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) { |
659 // An UnsafeTrap() (or for that matter, a Trap()) has to report error | 661 // An UnsafeTrap() (or for that matter, a Trap()) has to report error |
660 // conditions by returning an exit code in the range -1..-4096. This | 662 // conditions by returning an exit code in the range -1..-4096. This |
661 // should happen automatically if using ForwardSyscall(). If the TrapFnc() | 663 // should happen automatically if using ForwardSyscall(). If the TrapFnc() |
662 // uses some other method to make system calls, then it is responsible | 664 // uses some other method to make system calls, then it is responsible |
663 // for computing the correct return code. | 665 // for computing the correct return code. |
664 // This test verifies that ForwardSyscall() does the correct thing. | 666 // This test verifies that ForwardSyscall() does the correct thing. |
665 | 667 |
666 // The glibc system wrapper will ultimately set errno for us. So, from normal | 668 // The glibc system wrapper will ultimately set errno for us. So, from normal |
667 // userspace, all of this should be completely transparent. | 669 // userspace, all of this should be completely transparent. |
668 errno = 0; | 670 errno = 0; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
802 int cpu_info_access = access("/proc/cpuinfo", R_OK); | 804 int cpu_info_access = access("/proc/cpuinfo", R_OK); |
803 BPF_ASSERT(cpu_info_access == 0); | 805 BPF_ASSERT(cpu_info_access == 0); |
804 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); | 806 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); |
805 BPF_ASSERT(cpu_info_fd >= 0); | 807 BPF_ASSERT(cpu_info_fd >= 0); |
806 char buf[1024]; | 808 char buf[1024]; |
807 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); | 809 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); |
808 } | 810 } |
809 | 811 |
810 // Simple test demonstrating how to use SandboxBPF::Cond() | 812 // Simple test demonstrating how to use SandboxBPF::Cond() |
811 | 813 |
812 ErrorCode SimpleCondTestPolicy(SandboxBPF* sandbox, int sysno, void*) { | 814 class SimpleCondTestPolicy : public SandboxBPFPolicy { |
813 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 815 public: |
814 // FIXME: we should really not have to do that in a trivial policy | 816 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
815 return ErrorCode(ENOSYS); | 817 int sysno) const OVERRIDE; |
816 } | 818 }; |
819 | |
820 ErrorCode SimpleCondTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
821 int sysno) const { | |
822 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
817 | 823 |
818 // We deliberately return unusual errno values upon failure, so that we | 824 // We deliberately return unusual errno values upon failure, so that we |
819 // can uniquely test for these values. In a "real" policy, you would want | 825 // can uniquely test for these values. In a "real" policy, you would want |
820 // to return more traditional values. | 826 // to return more traditional values. |
821 switch (sysno) { | 827 switch (sysno) { |
822 #if defined(ANDROID) | 828 #if defined(ANDROID) |
823 case __NR_openat: // open is a wrapper of openat in android | 829 case __NR_openat: // open is a wrapper of openat in android |
824 // Allow opening files for reading, but don't allow writing. | 830 // Allow opening files for reading, but don't allow writing. |
825 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); | 831 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits); |
826 return sandbox->Cond(2, | 832 return sandbox->Cond(2, |
(...skipping 25 matching lines...) Expand all Loading... | |
852 ErrorCode::TP_32BIT, | 858 ErrorCode::TP_32BIT, |
853 ErrorCode::OP_EQUAL, | 859 ErrorCode::OP_EQUAL, |
854 PR_GET_DUMPABLE, | 860 PR_GET_DUMPABLE, |
855 ErrorCode(ErrorCode::ERR_ALLOWED), | 861 ErrorCode(ErrorCode::ERR_ALLOWED), |
856 ErrorCode(ENOMEM))); | 862 ErrorCode(ENOMEM))); |
857 default: | 863 default: |
858 return ErrorCode(ErrorCode::ERR_ALLOWED); | 864 return ErrorCode(ErrorCode::ERR_ALLOWED); |
859 } | 865 } |
860 } | 866 } |
861 | 867 |
862 BPF_TEST(SandboxBPF, SimpleCondTest, SimpleCondTestPolicy) { | 868 BPF_TEST_C(SandboxBPF, SimpleCondTest, SimpleCondTestPolicy) { |
863 int fd; | 869 int fd; |
864 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); | 870 BPF_ASSERT((fd = open("/proc/self/comm", O_RDWR)) == -1); |
865 BPF_ASSERT(errno == EROFS); | 871 BPF_ASSERT(errno == EROFS); |
866 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); | 872 BPF_ASSERT((fd = open("/proc/self/comm", O_RDONLY)) >= 0); |
867 close(fd); | 873 close(fd); |
868 | 874 |
869 int ret; | 875 int ret; |
870 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); | 876 BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0); |
871 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0); | 877 BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0); |
872 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); | 878 BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1); |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1181 return aux->Policy(sandbox, sysno); | 1187 return aux->Policy(sandbox, sysno); |
1182 } | 1188 } |
1183 | 1189 |
1184 BPF_TEST(SandboxBPF, | 1190 BPF_TEST(SandboxBPF, |
1185 EqualityTests, | 1191 EqualityTests, |
1186 EqualityStressTestPolicy, | 1192 EqualityStressTestPolicy, |
1187 EqualityStressTest /* (*BPF_AUX) */) { | 1193 EqualityStressTest /* (*BPF_AUX) */) { |
1188 BPF_AUX->VerifyFilter(); | 1194 BPF_AUX->VerifyFilter(); |
1189 } | 1195 } |
1190 | 1196 |
1191 ErrorCode EqualityArgumentWidthPolicy(SandboxBPF* sandbox, int sysno, void*) { | 1197 class EqualityArgumentWidthPolicy : public SandboxBPFPolicy { |
1192 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1198 public: |
1193 // FIXME: we should really not have to do that in a trivial policy | 1199 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
1194 return ErrorCode(ENOSYS); | 1200 int sysno) const OVERRIDE; |
1195 } else if (sysno == __NR_uname) { | 1201 }; |
1202 | |
1203 ErrorCode EqualityArgumentWidthPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
1204 int sysno) const { | |
1205 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
1206 if (sysno == __NR_uname) { | |
1196 return sandbox->Cond( | 1207 return sandbox->Cond( |
1197 0, | 1208 0, |
1198 ErrorCode::TP_32BIT, | 1209 ErrorCode::TP_32BIT, |
1199 ErrorCode::OP_EQUAL, | 1210 ErrorCode::OP_EQUAL, |
1200 0, | 1211 0, |
1201 sandbox->Cond(1, | 1212 sandbox->Cond(1, |
1202 ErrorCode::TP_32BIT, | 1213 ErrorCode::TP_32BIT, |
1203 ErrorCode::OP_EQUAL, | 1214 ErrorCode::OP_EQUAL, |
1204 0x55555555, | 1215 0x55555555, |
1205 ErrorCode(1), | 1216 ErrorCode(1), |
1206 ErrorCode(2)), | 1217 ErrorCode(2)), |
1207 // The BPF compiler and the BPF interpreter in the kernel are | 1218 // The BPF compiler and the BPF interpreter in the kernel are |
1208 // (mostly) agnostic of the host platform's word size. The compiler | 1219 // (mostly) agnostic of the host platform's word size. The compiler |
1209 // will happily generate code that tests a 64bit value, and the | 1220 // will happily generate code that tests a 64bit value, and the |
1210 // interpreter will happily perform this test. | 1221 // interpreter will happily perform this test. |
1211 // But unless there is a kernel bug, there is no way for us to pass | 1222 // But unless there is a kernel bug, there is no way for us to pass |
1212 // in a 64bit quantity on a 32bit platform. The upper 32bits should | 1223 // in a 64bit quantity on a 32bit platform. The upper 32bits should |
1213 // always be zero. So, this test should always evaluate as false on | 1224 // always be zero. So, this test should always evaluate as false on |
1214 // 32bit systems. | 1225 // 32bit systems. |
1215 sandbox->Cond(1, | 1226 sandbox->Cond(1, |
1216 ErrorCode::TP_64BIT, | 1227 ErrorCode::TP_64BIT, |
1217 ErrorCode::OP_EQUAL, | 1228 ErrorCode::OP_EQUAL, |
1218 0x55555555AAAAAAAAULL, | 1229 0x55555555AAAAAAAAULL, |
1219 ErrorCode(1), | 1230 ErrorCode(1), |
1220 ErrorCode(2))); | 1231 ErrorCode(2))); |
1221 } else { | |
1222 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1223 } | 1232 } |
1233 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1224 } | 1234 } |
1225 | 1235 |
1226 BPF_TEST(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { | 1236 BPF_TEST_C(SandboxBPF, EqualityArgumentWidth, EqualityArgumentWidthPolicy) { |
1227 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); | 1237 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0x55555555) == -1); |
1228 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); | 1238 BPF_ASSERT(SandboxSyscall(__NR_uname, 0, 0xAAAAAAAA) == -2); |
1229 #if __SIZEOF_POINTER__ > 4 | 1239 #if __SIZEOF_POINTER__ > 4 |
1230 // On 32bit machines, there is no way to pass a 64bit argument through the | 1240 // On 32bit machines, there is no way to pass a 64bit argument through the |
1231 // syscall interface. So, we have to skip the part of the test that requires | 1241 // syscall interface. So, we have to skip the part of the test that requires |
1232 // 64bit arguments. | 1242 // 64bit arguments. |
1233 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); | 1243 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555AAAAAAAAULL) == -1); |
1234 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); | 1244 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555500000000ULL) == -2); |
1235 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); | 1245 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x5555555511111111ULL) == -2); |
1236 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); | 1246 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x11111111AAAAAAAAULL) == -2); |
1237 #else | 1247 #else |
1238 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); | 1248 BPF_ASSERT(SandboxSyscall(__NR_uname, 1, 0x55555555) == -2); |
1239 #endif | 1249 #endif |
1240 } | 1250 } |
1241 | 1251 |
1242 #if __SIZEOF_POINTER__ > 4 | 1252 #if __SIZEOF_POINTER__ > 4 |
1243 // On 32bit machines, there is no way to pass a 64bit argument through the | 1253 // On 32bit machines, there is no way to pass a 64bit argument through the |
1244 // syscall interface. So, we have to skip the part of the test that requires | 1254 // syscall interface. So, we have to skip the part of the test that requires |
1245 // 64bit arguments. | 1255 // 64bit arguments. |
1246 BPF_DEATH_TEST(SandboxBPF, | 1256 BPF_DEATH_TEST_C(SandboxBPF, |
1247 EqualityArgumentUnallowed64bit, | 1257 EqualityArgumentUnallowed64bit, |
1248 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1258 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
1249 EqualityArgumentWidthPolicy) { | 1259 EqualityArgumentWidthPolicy) { |
1250 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); | 1260 SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL); |
1251 } | 1261 } |
1252 #endif | 1262 #endif |
1253 | 1263 |
1254 ErrorCode EqualityWithNegativeArgumentsPolicy(SandboxBPF* sandbox, | 1264 class EqualityWithNegativeArgumentsPolicy : public SandboxBPFPolicy { |
1255 int sysno, | 1265 public: |
1256 void*) { | 1266 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, |
1257 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1267 int sysno) const OVERRIDE { |
1258 // FIXME: we should really not have to do that in a trivial policy | 1268 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); |
1259 return ErrorCode(ENOSYS); | 1269 if (sysno == __NR_uname) { |
1260 } else if (sysno == __NR_uname) { | 1270 return sandbox->Cond(0, |
1261 return sandbox->Cond(0, | 1271 ErrorCode::TP_32BIT, |
1262 ErrorCode::TP_32BIT, | 1272 ErrorCode::OP_EQUAL, |
1263 ErrorCode::OP_EQUAL, | 1273 0xFFFFFFFF, |
1264 0xFFFFFFFF, | 1274 ErrorCode(1), |
1265 ErrorCode(1), | 1275 ErrorCode(2)); |
1266 ErrorCode(2)); | 1276 } |
1267 } else { | |
1268 return ErrorCode(ErrorCode::ERR_ALLOWED); | 1277 return ErrorCode(ErrorCode::ERR_ALLOWED); |
1269 } | 1278 } |
1270 } | 1279 }; |
1271 | 1280 |
1272 BPF_TEST(SandboxBPF, | 1281 BPF_TEST_C(SandboxBPF, |
1273 EqualityWithNegativeArguments, | 1282 EqualityWithNegativeArguments, |
1274 EqualityWithNegativeArgumentsPolicy) { | 1283 EqualityWithNegativeArgumentsPolicy) { |
1275 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); | 1284 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1); |
1276 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); | 1285 BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1); |
1277 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); | 1286 BPF_ASSERT(SandboxSyscall(__NR_uname, -1LL) == -1); |
1278 } | 1287 } |
1279 | 1288 |
1280 #if __SIZEOF_POINTER__ > 4 | 1289 #if __SIZEOF_POINTER__ > 4 |
1281 BPF_DEATH_TEST(SandboxBPF, | 1290 BPF_DEATH_TEST_C(SandboxBPF, |
1282 EqualityWithNegative64bitArguments, | 1291 EqualityWithNegative64bitArguments, |
1283 DEATH_MESSAGE("Unexpected 64bit argument detected"), | 1292 DEATH_MESSAGE("Unexpected 64bit argument detected"), |
1284 EqualityWithNegativeArgumentsPolicy) { | 1293 EqualityWithNegativeArgumentsPolicy) { |
1285 // When expecting a 32bit system call argument, we look at the MSB of the | 1294 // When expecting a 32bit system call argument, we look at the MSB of the |
1286 // 64bit value and allow both "0" and "-1". But the latter is allowed only | 1295 // 64bit value and allow both "0" and "-1". But the latter is allowed only |
1287 // iff the LSB was negative. So, this death test should error out. | 1296 // iff the LSB was negative. So, this death test should error out. |
1288 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); | 1297 BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1); |
1289 } | 1298 } |
1290 #endif | 1299 #endif |
1291 ErrorCode AllBitTestPolicy(SandboxBPF* sandbox, int sysno, void *) { | 1300 class AllBitTestPolicy : public SandboxBPFPolicy { |
1301 public: | |
1302 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | |
1303 int sysno) const OVERRIDE; | |
1304 }; | |
1305 | |
1306 ErrorCode AllBitTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
1307 int sysno) const { | |
1308 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
1292 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of | 1309 // Test the OP_HAS_ALL_BITS conditional test operator with a couple of |
1293 // different bitmasks. We try to find bitmasks that could conceivably | 1310 // different bitmasks. We try to find bitmasks that could conceivably |
1294 // touch corner cases. | 1311 // touch corner cases. |
1295 // For all of these tests, we override the uname(). We can make use with | 1312 // For all of these tests, we override the uname(). We can make use with |
1296 // a single system call number, as we use the first system call argument to | 1313 // a single system call number, as we use the first system call argument to |
1297 // select the different bit masks that we want to test against. | 1314 // select the different bit masks that we want to test against. |
1298 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1315 if (sysno == __NR_uname) { |
1299 // FIXME: we should really not have to do that in a trivial policy | |
1300 return ErrorCode(ENOSYS); | |
1301 } else if (sysno == __NR_uname) { | |
1302 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1316 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
1303 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1317 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
1304 0x0, | 1318 0x0, |
1305 ErrorCode(1), ErrorCode(0)), | 1319 ErrorCode(1), ErrorCode(0)), |
1306 | 1320 |
1307 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, | 1321 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, |
1308 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, | 1322 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ALL_BITS, |
1309 0x1, | 1323 0x1, |
1310 ErrorCode(1), ErrorCode(0)), | 1324 ErrorCode(1), ErrorCode(0)), |
1311 | 1325 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1347 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | 1361 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
1348 0x300000000ULL, | 1362 0x300000000ULL, |
1349 ErrorCode(1), ErrorCode(0)), | 1363 ErrorCode(1), ErrorCode(0)), |
1350 | 1364 |
1351 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, | 1365 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, |
1352 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, | 1366 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ALL_BITS, |
1353 0x100000001ULL, | 1367 0x100000001ULL, |
1354 ErrorCode(1), ErrorCode(0)), | 1368 ErrorCode(1), ErrorCode(0)), |
1355 | 1369 |
1356 sandbox->Kill("Invalid test case number")))))))))))); | 1370 sandbox->Kill("Invalid test case number")))))))))))); |
1357 } else { | |
1358 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1359 } | 1371 } |
1372 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1360 } | 1373 } |
1361 | 1374 |
1362 // Define a macro that performs tests using our test policy. | 1375 // Define a macro that performs tests using our test policy. |
1363 // NOTE: Not all of the arguments in this macro are actually used! | 1376 // NOTE: Not all of the arguments in this macro are actually used! |
1364 // They are here just to serve as documentation of the conditions | 1377 // They are here just to serve as documentation of the conditions |
1365 // implemented in the test policy. | 1378 // implemented in the test policy. |
1366 // Most notably, "op" and "mask" are unused by the macro. If you want | 1379 // Most notably, "op" and "mask" are unused by the macro. If you want |
1367 // to make changes to these values, you will have to edit the | 1380 // to make changes to these values, you will have to edit the |
1368 // test policy instead. | 1381 // test policy instead. |
1369 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ | 1382 #define BITMASK_TEST(testcase, arg, op, mask, expected_value) \ |
1370 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) | 1383 BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value)) |
1371 | 1384 |
1372 // Our uname() system call returns ErrorCode(1) for success and | 1385 // Our uname() system call returns ErrorCode(1) for success and |
1373 // ErrorCode(0) for failure. SandboxSyscall() turns this into an | 1386 // ErrorCode(0) for failure. SandboxSyscall() turns this into an |
1374 // exit code of -1 or 0. | 1387 // exit code of -1 or 0. |
1375 #define EXPECT_FAILURE 0 | 1388 #define EXPECT_FAILURE 0 |
1376 #define EXPECT_SUCCESS -1 | 1389 #define EXPECT_SUCCESS -1 |
1377 | 1390 |
1378 // A couple of our tests behave differently on 32bit and 64bit systems, as | 1391 // A couple of our tests behave differently on 32bit and 64bit systems, as |
1379 // there is no way for a 32bit system call to pass in a 64bit system call | 1392 // there is no way for a 32bit system call to pass in a 64bit system call |
1380 // argument "arg". | 1393 // argument "arg". |
1381 // We expect these tests to succeed on 64bit systems, but to tail on 32bit | 1394 // We expect these tests to succeed on 64bit systems, but to tail on 32bit |
1382 // systems. | 1395 // systems. |
1383 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) | 1396 #define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE) |
1384 BPF_TEST(SandboxBPF, AllBitTests, AllBitTestPolicy) { | 1397 BPF_TEST_C(SandboxBPF, AllBitTests, AllBitTestPolicy) { |
1385 // 32bit test: all of 0x0 (should always be true) | 1398 // 32bit test: all of 0x0 (should always be true) |
1386 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); | 1399 BITMASK_TEST( 0, 0, ALLBITS32, 0, EXPECT_SUCCESS); |
1387 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); | 1400 BITMASK_TEST( 0, 1, ALLBITS32, 0, EXPECT_SUCCESS); |
1388 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); | 1401 BITMASK_TEST( 0, 3, ALLBITS32, 0, EXPECT_SUCCESS); |
1389 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); | 1402 BITMASK_TEST( 0, 0xFFFFFFFFU, ALLBITS32, 0, EXPECT_SUCCESS); |
1390 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); | 1403 BITMASK_TEST( 0, -1LL, ALLBITS32, 0, EXPECT_SUCCESS); |
1391 | 1404 |
1392 // 32bit test: all of 0x1 | 1405 // 32bit test: all of 0x1 |
1393 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); | 1406 BITMASK_TEST( 1, 0, ALLBITS32, 0x1, EXPECT_FAILURE); |
1394 BITMASK_TEST( 1, 1, ALLBITS32, 0x1, EXPECT_SUCCESS); | 1407 BITMASK_TEST( 1, 1, ALLBITS32, 0x1, EXPECT_SUCCESS); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1477 | 1490 |
1478 // 64bit test: all of 0x100000001 | 1491 // 64bit test: all of 0x100000001 |
1479 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1492 BITMASK_TEST(10, 0x000000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1480 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1493 BITMASK_TEST(10, 0x000000001LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1481 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1494 BITMASK_TEST(10, 0x100000000LL, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1482 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1495 BITMASK_TEST(10, 0x100000001LL, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
1483 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); | 1496 BITMASK_TEST(10, 0xFFFFFFFFU, ALLBITS64,0x100000001, EXPECT_FAILURE); |
1484 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); | 1497 BITMASK_TEST(10, -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS); |
1485 } | 1498 } |
1486 | 1499 |
1487 ErrorCode AnyBitTestPolicy(SandboxBPF* sandbox, int sysno, void*) { | 1500 class AnyBitTestPolicy : public SandboxBPFPolicy { |
1501 public: | |
1502 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | |
1503 int sysno) const OVERRIDE; | |
1504 }; | |
1505 | |
1506 ErrorCode AnyBitTestPolicy::EvaluateSyscall(SandboxBPF* sandbox, | |
1507 int sysno) const { | |
1508 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
1488 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of | 1509 // Test the OP_HAS_ANY_BITS conditional test operator with a couple of |
1489 // different bitmasks. We try to find bitmasks that could conceivably | 1510 // different bitmasks. We try to find bitmasks that could conceivably |
1490 // touch corner cases. | 1511 // touch corner cases. |
1491 // For all of these tests, we override the uname(). We can make use with | 1512 // For all of these tests, we override the uname(). We can make use with |
1492 // a single system call number, as we use the first system call argument to | 1513 // a single system call number, as we use the first system call argument to |
1493 // select the different bit masks that we want to test against. | 1514 // select the different bit masks that we want to test against. |
1494 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1515 if (sysno == __NR_uname) { |
1495 // FIXME: we should really not have to do that in a trivial policy | |
1496 return ErrorCode(ENOSYS); | |
1497 } else if (sysno == __NR_uname) { | |
1498 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, | 1516 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0, |
1499 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1517 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
1500 0x0, | 1518 0x0, |
1501 ErrorCode(1), ErrorCode(0)), | 1519 ErrorCode(1), ErrorCode(0)), |
1502 | 1520 |
1503 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, | 1521 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 1, |
1504 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1522 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
1505 0x1, | 1523 0x1, |
1506 ErrorCode(1), ErrorCode(0)), | 1524 ErrorCode(1), ErrorCode(0)), |
1507 | 1525 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1546 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1564 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
1547 0x300000000ULL, | 1565 0x300000000ULL, |
1548 ErrorCode(1), ErrorCode(0)), | 1566 ErrorCode(1), ErrorCode(0)), |
1549 | 1567 |
1550 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, | 1568 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 10, |
1551 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, | 1569 sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_HAS_ANY_BITS, |
1552 0x100000001ULL, | 1570 0x100000001ULL, |
1553 ErrorCode(1), ErrorCode(0)), | 1571 ErrorCode(1), ErrorCode(0)), |
1554 | 1572 |
1555 sandbox->Kill("Invalid test case number")))))))))))); | 1573 sandbox->Kill("Invalid test case number")))))))))))); |
1556 } else { | |
1557 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1558 } | 1574 } |
1575 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1559 } | 1576 } |
1560 | 1577 |
1561 BPF_TEST(SandboxBPF, AnyBitTests, AnyBitTestPolicy) { | 1578 BPF_TEST_C(SandboxBPF, AnyBitTests, AnyBitTestPolicy) { |
1562 // 32bit test: any of 0x0 (should always be false) | 1579 // 32bit test: any of 0x0 (should always be false) |
1563 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); | 1580 BITMASK_TEST( 0, 0, ANYBITS32, 0x0, EXPECT_FAILURE); |
1564 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); | 1581 BITMASK_TEST( 0, 1, ANYBITS32, 0x0, EXPECT_FAILURE); |
1565 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); | 1582 BITMASK_TEST( 0, 3, ANYBITS32, 0x0, EXPECT_FAILURE); |
1566 BITMASK_TEST( 0, 0xFFFFFFFFU, ANYBITS32, 0x0, EXPECT_FAILURE); | 1583 BITMASK_TEST( 0, 0xFFFFFFFFU, ANYBITS32, 0x0, EXPECT_FAILURE); |
1567 BITMASK_TEST( 0, -1LL, ANYBITS32, 0x0, EXPECT_FAILURE); | 1584 BITMASK_TEST( 0, -1LL, ANYBITS32, 0x0, EXPECT_FAILURE); |
1568 | 1585 |
1569 // 32bit test: any of 0x1 | 1586 // 32bit test: any of 0x1 |
1570 BITMASK_TEST( 1, 0, ANYBITS32, 0x1, EXPECT_FAILURE); | 1587 BITMASK_TEST( 1, 0, ANYBITS32, 0x1, EXPECT_FAILURE); |
1571 BITMASK_TEST( 1, 1, ANYBITS32, 0x1, EXPECT_SUCCESS); | 1588 BITMASK_TEST( 1, 1, ANYBITS32, 0x1, EXPECT_SUCCESS); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1681 (long long)args.args[0], | 1698 (long long)args.args[0], |
1682 (long long)args.args[1], | 1699 (long long)args.args[1], |
1683 (long long)args.args[2], | 1700 (long long)args.args[2], |
1684 (long long)args.args[3], | 1701 (long long)args.args[3], |
1685 (long long)args.args[4], | 1702 (long long)args.args[4], |
1686 (long long)args.args[5], | 1703 (long long)args.args[5], |
1687 msg); | 1704 msg); |
1688 } | 1705 } |
1689 return -EPERM; | 1706 return -EPERM; |
1690 } | 1707 } |
1691 ErrorCode PthreadPolicyEquality(SandboxBPF* sandbox, int sysno, void* aux) { | 1708 |
1709 class PthreadPolicyEquality : public SandboxBPFPolicy { | |
1710 public: | |
1711 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | |
1712 int sysno) const OVERRIDE; | |
1713 }; | |
1714 | |
1715 ErrorCode PthreadPolicyEquality::EvaluateSyscall(SandboxBPF* sandbox, | |
1716 int sysno) const { | |
1717 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
1692 // This policy allows creating threads with pthread_create(). But it | 1718 // This policy allows creating threads with pthread_create(). But it |
1693 // doesn't allow any other uses of clone(). Most notably, it does not | 1719 // doesn't allow any other uses of clone(). Most notably, it does not |
1694 // allow callers to implement fork() or vfork() by passing suitable flags | 1720 // allow callers to implement fork() or vfork() by passing suitable flags |
1695 // to the clone() system call. | 1721 // to the clone() system call. |
1696 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1722 if (sysno == __NR_clone) { |
1697 // FIXME: we should really not have to do that in a trivial policy | |
1698 return ErrorCode(ENOSYS); | |
1699 } else if (sysno == __NR_clone) { | |
1700 // We have seen two different valid combinations of flags. Glibc | 1723 // We have seen two different valid combinations of flags. Glibc |
1701 // uses the more modern flags, sets the TLS from the call to clone(), and | 1724 // uses the more modern flags, sets the TLS from the call to clone(), and |
1702 // uses futexes to monitor threads. Android's C run-time library, doesn't | 1725 // uses futexes to monitor threads. Android's C run-time library, doesn't |
1703 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. | 1726 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
1704 // More recent versions of Android don't set CLONE_DETACHED anymore, so | 1727 // More recent versions of Android don't set CLONE_DETACHED anymore, so |
1705 // the last case accounts for that. | 1728 // the last case accounts for that. |
1706 // The following policy is very strict. It only allows the exact masks | 1729 // The following policy is very strict. It only allows the exact masks |
1707 // that we have seen in known implementations. It is probably somewhat | 1730 // that we have seen in known implementations. It is probably somewhat |
1708 // stricter than what we would want to do. | 1731 // stricter than what we would want to do. |
1709 const uint64_t kGlibcCloneMask = | 1732 const uint64_t kGlibcCloneMask = |
1710 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | | 1733 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | |
1711 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | | 1734 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | |
1712 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; | 1735 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; |
1713 const uint64_t kBaseAndroidCloneMask = | 1736 const uint64_t kBaseAndroidCloneMask = |
1714 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | | 1737 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | |
1715 CLONE_THREAD | CLONE_SYSVSEM; | 1738 CLONE_THREAD | CLONE_SYSVSEM; |
1716 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1739 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
1717 kGlibcCloneMask, | 1740 kGlibcCloneMask, |
1718 ErrorCode(ErrorCode::ERR_ALLOWED), | 1741 ErrorCode(ErrorCode::ERR_ALLOWED), |
1719 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1742 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
1720 kBaseAndroidCloneMask | CLONE_DETACHED, | 1743 kBaseAndroidCloneMask | CLONE_DETACHED, |
1721 ErrorCode(ErrorCode::ERR_ALLOWED), | 1744 ErrorCode(ErrorCode::ERR_ALLOWED), |
1722 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, | 1745 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
1723 kBaseAndroidCloneMask, | 1746 kBaseAndroidCloneMask, |
1724 ErrorCode(ErrorCode::ERR_ALLOWED), | 1747 ErrorCode(ErrorCode::ERR_ALLOWED), |
1725 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); | 1748 sandbox->Trap(PthreadTrapHandler, "Unknown mask")))); |
1726 } else { | |
1727 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1728 } | 1749 } |
1750 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1729 } | 1751 } |
1730 | 1752 |
1731 ErrorCode PthreadPolicyBitMask(SandboxBPF* sandbox, int sysno, void* aux) { | 1753 class PthreadPolicyBitMask : public SandboxBPFPolicy { |
1754 public: | |
1755 virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox, | |
1756 int sysno) const OVERRIDE; | |
1757 }; | |
1758 | |
1759 ErrorCode PthreadPolicyBitMask::EvaluateSyscall(SandboxBPF* sandbox, | |
1760 int sysno) const { | |
1761 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno)); | |
1732 // This policy allows creating threads with pthread_create(). But it | 1762 // This policy allows creating threads with pthread_create(). But it |
1733 // doesn't allow any other uses of clone(). Most notably, it does not | 1763 // doesn't allow any other uses of clone(). Most notably, it does not |
1734 // allow callers to implement fork() or vfork() by passing suitable flags | 1764 // allow callers to implement fork() or vfork() by passing suitable flags |
1735 // to the clone() system call. | 1765 // to the clone() system call. |
1736 if (!SandboxBPF::IsValidSyscallNumber(sysno)) { | 1766 if (sysno == __NR_clone) { |
1737 // FIXME: we should really not have to do that in a trivial policy | |
1738 return ErrorCode(ENOSYS); | |
1739 } else if (sysno == __NR_clone) { | |
1740 // We have seen two different valid combinations of flags. Glibc | 1767 // We have seen two different valid combinations of flags. Glibc |
1741 // uses the more modern flags, sets the TLS from the call to clone(), and | 1768 // uses the more modern flags, sets the TLS from the call to clone(), and |
1742 // uses futexes to monitor threads. Android's C run-time library, doesn't | 1769 // uses futexes to monitor threads. Android's C run-time library, doesn't |
1743 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. | 1770 // do any of this, but it sets the obsolete (and no-op) CLONE_DETACHED. |
1744 // The following policy allows for either combination of flags, but it | 1771 // The following policy allows for either combination of flags, but it |
1745 // is generally a little more conservative than strictly necessary. We | 1772 // is generally a little more conservative than strictly necessary. We |
1746 // err on the side of rather safe than sorry. | 1773 // err on the side of rather safe than sorry. |
1747 // Very noticeably though, we disallow fork() (which is often just a | 1774 // Very noticeably though, we disallow fork() (which is often just a |
1748 // wrapper around clone()). | 1775 // wrapper around clone()). |
1749 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1776 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
(...skipping 11 matching lines...) Expand all Loading... | |
1761 ErrorCode(ErrorCode::ERR_ALLOWED), | 1788 ErrorCode(ErrorCode::ERR_ALLOWED), |
1762 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, | 1789 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS, |
1763 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, | 1790 CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, |
1764 sandbox->Trap(PthreadTrapHandler, | 1791 sandbox->Trap(PthreadTrapHandler, |
1765 "Must set either all or none of the TLS" | 1792 "Must set either all or none of the TLS" |
1766 " and futex bits in call to clone()"), | 1793 " and futex bits in call to clone()"), |
1767 ErrorCode(ErrorCode::ERR_ALLOWED))), | 1794 ErrorCode(ErrorCode::ERR_ALLOWED))), |
1768 sandbox->Trap(PthreadTrapHandler, | 1795 sandbox->Trap(PthreadTrapHandler, |
1769 "Missing mandatory CLONE_XXX flags " | 1796 "Missing mandatory CLONE_XXX flags " |
1770 "when creating new thread"))); | 1797 "when creating new thread"))); |
1771 } else { | |
1772 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1773 } | 1798 } |
1799 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
1774 } | 1800 } |
1775 | 1801 |
1776 static void* ThreadFnc(void* arg) { | 1802 static void* ThreadFnc(void* arg) { |
1777 ++*reinterpret_cast<int*>(arg); | 1803 ++*reinterpret_cast<int*>(arg); |
1778 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); | 1804 SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0); |
1779 return NULL; | 1805 return NULL; |
1780 } | 1806 } |
1781 | 1807 |
1782 static void PthreadTest() { | 1808 static void PthreadTest() { |
1783 // Attempt to start a joinable thread. This should succeed. | 1809 // Attempt to start a joinable thread. This should succeed. |
(...skipping 21 matching lines...) Expand all Loading... | |
1805 // run-time libraries other than glibc might call __NR_fork instead of | 1831 // run-time libraries other than glibc might call __NR_fork instead of |
1806 // __NR_clone, and that would introduce a bogus test failure. | 1832 // __NR_clone, and that would introduce a bogus test failure. |
1807 int pid; | 1833 int pid; |
1808 BPF_ASSERT(SandboxSyscall(__NR_clone, | 1834 BPF_ASSERT(SandboxSyscall(__NR_clone, |
1809 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, | 1835 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, |
1810 0, | 1836 0, |
1811 0, | 1837 0, |
1812 &pid) == -EPERM); | 1838 &pid) == -EPERM); |
1813 } | 1839 } |
1814 | 1840 |
1815 BPF_TEST(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); } | 1841 BPF_TEST_C(SandboxBPF, PthreadEquality, PthreadPolicyEquality) { |
1842 PthreadTest(); | |
1843 } | |
1816 | 1844 |
1817 BPF_TEST(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); } | 1845 BPF_TEST_C(SandboxBPF, PthreadBitMask, PthreadPolicyBitMask) { |
1846 PthreadTest(); | |
1847 } | |
1818 | 1848 |
1819 } // namespace | 1849 } // namespace |
1820 | 1850 |
1821 } // namespace sandbox | 1851 } // namespace sandbox |
OLD | NEW |