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 <sys/prctl.h> | 5 #include <sys/prctl.h> |
6 #include <sys/utsname.h> | 6 #include <sys/utsname.h> |
7 | 7 |
8 #include <ostream> | 8 #include <ostream> |
9 | 9 |
10 #include "base/memory/scoped_ptr.h" | |
10 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" | 11 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
11 #include "sandbox/linux/seccomp-bpf/verifier.h" | 12 #include "sandbox/linux/seccomp-bpf/verifier.h" |
13 #include "sandbox/linux/services/broker_process.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
13 | 15 |
14 using namespace playground2; | 16 using namespace playground2; |
17 using sandbox::BrokerProcess; | |
15 | 18 |
16 namespace { | 19 namespace { |
17 | 20 |
18 const int kExpectedReturnValue = 42; | 21 const int kExpectedReturnValue = 42; |
19 | 22 |
20 // This test should execute no matter whether we have kernel support. So, | 23 // This test should execute no matter whether we have kernel support. So, |
21 // we make it a TEST() instead of a BPF_TEST(). | 24 // we make it a TEST() instead of a BPF_TEST(). |
22 TEST(SandboxBpf, CallSupports) { | 25 TEST(SandboxBpf, CallSupports) { |
23 // We check that we don't crash, but it's ok if the kernel doesn't | 26 // We check that we don't crash, but it's ok if the kernel doesn't |
24 // support it. | 27 // support it. |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 // would make system calls, but it allows us to verify that we don't | 476 // would make system calls, but it allows us to verify that we don't |
474 // accidentally mess with errno, when we shouldn't. | 477 // accidentally mess with errno, when we shouldn't. |
475 errno = 0; | 478 errno = 0; |
476 struct arch_seccomp_data args = { }; | 479 struct arch_seccomp_data args = { }; |
477 args.nr = __NR_close; | 480 args.nr = __NR_close; |
478 args.args[0] = -1; | 481 args.args[0] = -1; |
479 BPF_ASSERT(Sandbox::ForwardSyscall(args) == -EBADF); | 482 BPF_ASSERT(Sandbox::ForwardSyscall(args) == -EBADF); |
480 BPF_ASSERT(errno == 0); | 483 BPF_ASSERT(errno == 0); |
481 } | 484 } |
482 | 485 |
486 // Test a trap handler that makes use of a broker process to open(). | |
487 | |
488 class InitializedOpenBroker { | |
489 public: | |
490 InitializedOpenBroker() : initialized_(false) { | |
491 std::vector<std::string> allowed_files; | |
492 allowed_files.push_back("/proc/allowed"); | |
493 allowed_files.push_back("/proc/cpuinfo"); | |
494 | |
495 broker_process_.reset(new BrokerProcess(allowed_files)); | |
496 BPF_ASSERT(broker_process() != NULL); | |
497 BPF_ASSERT(broker_process_->Init(NULL)); | |
498 | |
499 initialized_ = true; | |
500 } | |
501 bool initialized() { return initialized_; } | |
502 class BrokerProcess* broker_process() { return broker_process_.get(); } | |
503 private: | |
504 bool initialized_; | |
505 scoped_ptr<class BrokerProcess> broker_process_; | |
506 DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker); | |
507 }; | |
508 | |
509 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args, | |
510 void *aux) { | |
Markus (顧孟勤)
2012/12/13 09:48:52
I would probably have moved the TrapHandler inside
| |
511 BPF_ASSERT(aux); | |
512 BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux); | |
513 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]), | |
514 static_cast<int>(args.args[1])); | |
515 } | |
516 | |
517 ErrorCode DenyOpenPolicy(int sysno, void *aux) { | |
518 InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux); | |
Markus (顧孟勤)
2012/12/13 09:48:52
I probably also would have moved the body of this
| |
519 if (!Sandbox::isValidSyscallNumber(sysno)) { | |
520 return ErrorCode(ENOSYS); | |
521 } | |
522 | |
523 switch (sysno) { | |
524 case __NR_open: | |
525 case __NR_openat: | |
526 // We get a InitializedOpenBroker class, but our trap handler wants | |
527 // the BrokerProcess object. | |
528 return ErrorCode(Sandbox::Trap(BrokerOpenTrapHandler, | |
529 iob->broker_process())); | |
Markus (顧孟勤)
2012/12/13 09:48:52
Indentation is a little funny, I think
jln (very slow on Chromium)
2012/12/13 19:27:17
Done.
| |
530 default: | |
531 return ErrorCode(ErrorCode::ERR_ALLOWED); | |
532 } | |
533 } | |
534 | |
535 // We use a InitializedOpenBroker class since, so that we can run unsandboxed | |
Markus (顧孟勤)
2012/12/13 09:48:52
s/ since//
jln (very slow on Chromium)
2012/12/13 19:27:17
Done.
| |
536 // code in its constructor, which is the only way to do so in a BPF_TEST. | |
537 BPF_TEST(SandboxBpf, UseOpenBroker, DenyOpenPolicy, | |
538 class InitializedOpenBroker /* BPF_AUX */) { | |
Markus (顧孟勤)
2012/12/13 09:48:52
The "class" is superfluous here, and I don't think
jln (very slow on Chromium)
2012/12/13 19:27:17
Done.
| |
539 BPF_ASSERT(BPF_AUX.initialized()); | |
540 class BrokerProcess* broker_process = BPF_AUX.broker_process(); | |
541 BPF_ASSERT(broker_process != NULL); | |
542 | |
543 // First, use the broker "manually" | |
544 BPF_ASSERT(broker_process->Open("/proc/denied", O_RDONLY) == -EPERM); | |
545 BPF_ASSERT(broker_process->Open("/proc/allowed", O_RDONLY) == -ENOENT); | |
546 | |
547 // Now use glibc's open() as an external library would. | |
548 BPF_ASSERT(open("/proc/denied", O_RDONLY) == -1); | |
549 BPF_ASSERT(errno == EPERM); | |
550 | |
551 BPF_ASSERT(open("/proc/allowed", O_RDONLY) == -1); | |
552 BPF_ASSERT(errno == ENOENT); | |
553 | |
554 // This is also white listed and does exist. | |
555 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY); | |
556 BPF_ASSERT(cpu_info_fd >= 0); | |
557 char buf[1024]; | |
558 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0); | |
559 } | |
560 | |
483 } // namespace | 561 } // namespace |
OLD | NEW |