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