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

Side by Side Diff: sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc

Issue 289193003: Convert a bunch of BPF_TEST tests to use BPF_TEST_C (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase (demo.cc fix pushed into parent CL) Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698