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

Side by Side Diff: sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc

Issue 921563002: Linux Sandbox: reorganize (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix android_futex includes. Created 5 years, 10 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "sandbox/linux/bpf_dsl/bpf_dsl.h"
6
7 #include <errno.h> 5 #include <errno.h>
8 #include <fcntl.h> 6 #include <fcntl.h>
9 #include <pthread.h> 7 #include <pthread.h>
10 #include <sched.h> 8 #include <sched.h>
11 #include <signal.h> 9 #include <signal.h>
12 #include <sys/prctl.h> 10 #include <sys/prctl.h>
13 #include <sys/ptrace.h> 11 #include <sys/ptrace.h>
14 #include <sys/syscall.h> 12 #include <sys/syscall.h>
15 #include <sys/time.h> 13 #include <sys/time.h>
16 #include <sys/types.h> 14 #include <sys/types.h>
17 #include <sys/utsname.h> 15 #include <sys/utsname.h>
18 #include <unistd.h> 16 #include <unistd.h>
19 #include <sys/socket.h> 17 #include <sys/socket.h>
20 18
21 #if defined(ANDROID) 19 #if defined(ANDROID)
22 // Work-around for buggy headers in Android's NDK 20 // Work-around for buggy headers in Android's NDK
23 #define __user 21 #define __user
24 #endif 22 #endif
25 #include <linux/futex.h> 23 #include <linux/futex.h>
26 24
27 #include "base/bind.h" 25 #include "base/bind.h"
28 #include "base/logging.h" 26 #include "base/logging.h"
29 #include "base/macros.h" 27 #include "base/macros.h"
30 #include "base/memory/scoped_ptr.h" 28 #include "base/memory/scoped_ptr.h"
31 #include "base/posix/eintr_wrapper.h" 29 #include "base/posix/eintr_wrapper.h"
32 #include "base/synchronization/waitable_event.h" 30 #include "base/synchronization/waitable_event.h"
33 #include "base/sys_info.h" 31 #include "base/sys_info.h"
34 #include "base/threading/thread.h" 32 #include "base/threading/thread.h"
35 #include "build/build_config.h" 33 #include "build/build_config.h"
34 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
36 #include "sandbox/linux/bpf_dsl/policy.h" 35 #include "sandbox/linux/bpf_dsl/policy.h"
37 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" 36 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
38 #include "sandbox/linux/seccomp-bpf/die.h" 37 #include "sandbox/linux/seccomp-bpf/die.h"
39 #include "sandbox/linux/seccomp-bpf/errorcode.h" 38 #include "sandbox/linux/seccomp-bpf/errorcode.h"
40 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" 39 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
41 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 40 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
42 #include "sandbox/linux/seccomp-bpf/syscall.h" 41 #include "sandbox/linux/seccomp-bpf/syscall.h"
43 #include "sandbox/linux/seccomp-bpf/trap.h" 42 #include "sandbox/linux/seccomp-bpf/trap.h"
44 #include "sandbox/linux/services/linux_syscalls.h"
45 #include "sandbox/linux/services/syscall_wrappers.h" 43 #include "sandbox/linux/services/syscall_wrappers.h"
46 #include "sandbox/linux/services/thread_helpers.h" 44 #include "sandbox/linux/services/thread_helpers.h"
47 #include "sandbox/linux/syscall_broker/broker_file_permission.h" 45 #include "sandbox/linux/system_headers/linux_syscalls.h"
48 #include "sandbox/linux/syscall_broker/broker_process.h"
49 #include "sandbox/linux/tests/scoped_temporary_file.h" 46 #include "sandbox/linux/tests/scoped_temporary_file.h"
50 #include "sandbox/linux/tests/unit_tests.h" 47 #include "sandbox/linux/tests/unit_tests.h"
51 #include "testing/gtest/include/gtest/gtest.h" 48 #include "testing/gtest/include/gtest/gtest.h"
52 49
53 // Workaround for Android's prctl.h file. 50 // Workaround for Android's prctl.h file.
54 #ifndef PR_GET_ENDIAN 51 #ifndef PR_GET_ENDIAN
55 #define PR_GET_ENDIAN 19 52 #define PR_GET_ENDIAN 19
56 #endif 53 #endif
57 #ifndef PR_CAPBSET_READ 54 #ifndef PR_CAPBSET_READ
58 #define PR_CAPBSET_READ 23 55 #define PR_CAPBSET_READ 23
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 // would make system calls, but it allows us to verify that we don't 724 // would make system calls, but it allows us to verify that we don't
728 // accidentally mess with errno, when we shouldn't. 725 // accidentally mess with errno, when we shouldn't.
729 errno = 0; 726 errno = 0;
730 struct arch_seccomp_data args = {}; 727 struct arch_seccomp_data args = {};
731 args.nr = __NR_close; 728 args.nr = __NR_close;
732 args.args[0] = -1; 729 args.args[0] = -1;
733 BPF_ASSERT(SandboxBPF::ForwardSyscall(args) == -EBADF); 730 BPF_ASSERT(SandboxBPF::ForwardSyscall(args) == -EBADF);
734 BPF_ASSERT(errno == 0); 731 BPF_ASSERT(errno == 0);
735 } 732 }
736 733
737 bool NoOpCallback() {
738 return true;
739 }
740
741 // Test a trap handler that makes use of a broker process to open().
742
743 class InitializedOpenBroker {
744 public:
745 InitializedOpenBroker() : initialized_(false) {
746 std::vector<syscall_broker::BrokerFilePermission> permissions;
747 permissions.push_back(
748 syscall_broker::BrokerFilePermission::ReadOnly("/proc/allowed"));
749 permissions.push_back(
750 syscall_broker::BrokerFilePermission::ReadOnly("/proc/cpuinfo"));
751
752 broker_process_.reset(
753 new syscall_broker::BrokerProcess(EPERM, permissions));
754 BPF_ASSERT(broker_process() != NULL);
755 BPF_ASSERT(broker_process_->Init(base::Bind(&NoOpCallback)));
756
757 initialized_ = true;
758 }
759 bool initialized() { return initialized_; }
760 class syscall_broker::BrokerProcess* broker_process() {
761 return broker_process_.get();
762 }
763
764 private:
765 bool initialized_;
766 scoped_ptr<class syscall_broker::BrokerProcess> broker_process_;
767 DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker);
768 };
769
770 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args,
771 void* aux) {
772 BPF_ASSERT(aux);
773 syscall_broker::BrokerProcess* broker_process =
774 static_cast<syscall_broker::BrokerProcess*>(aux);
775 switch (args.nr) {
776 case __NR_faccessat: // access is a wrapper of faccessat in android
777 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD);
778 return broker_process->Access(reinterpret_cast<const char*>(args.args[1]),
779 static_cast<int>(args.args[2]));
780 #if defined(__NR_access)
781 case __NR_access:
782 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]),
783 static_cast<int>(args.args[1]));
784 #endif
785 #if defined(__NR_open)
786 case __NR_open:
787 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
788 static_cast<int>(args.args[1]));
789 #endif
790 case __NR_openat:
791 // We only call open() so if we arrive here, it's because glibc uses
792 // the openat() system call.
793 BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD);
794 return broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
795 static_cast<int>(args.args[2]));
796 default:
797 BPF_ASSERT(false);
798 return -ENOSYS;
799 }
800 }
801
802 class DenyOpenPolicy : public Policy {
803 public:
804 explicit DenyOpenPolicy(InitializedOpenBroker* iob) : iob_(iob) {}
805 ~DenyOpenPolicy() override {}
806
807 ResultExpr EvaluateSyscall(int sysno) const override {
808 DCHECK(SandboxBPF::IsValidSyscallNumber(sysno));
809
810 switch (sysno) {
811 case __NR_faccessat:
812 #if defined(__NR_access)
813 case __NR_access:
814 #endif
815 #if defined(__NR_open)
816 case __NR_open:
817 #endif
818 case __NR_openat:
819 // We get a InitializedOpenBroker class, but our trap handler wants
820 // the syscall_broker::BrokerProcess object.
821 return Trap(BrokerOpenTrapHandler, iob_->broker_process());
822 default:
823 return Allow();
824 }
825 }
826
827 private:
828 InitializedOpenBroker* iob_;
829
830 DISALLOW_COPY_AND_ASSIGN(DenyOpenPolicy);
831 };
832
833 // We use a InitializedOpenBroker class, so that we can run unsandboxed
834 // code in its constructor, which is the only way to do so in a BPF_TEST.
835 BPF_TEST(SandboxBPF,
836 UseOpenBroker,
837 DenyOpenPolicy,
838 InitializedOpenBroker /* (*BPF_AUX) */) {
839 BPF_ASSERT(BPF_AUX->initialized());
840 syscall_broker::BrokerProcess* broker_process = BPF_AUX->broker_process();
841 BPF_ASSERT(broker_process != NULL);
842
843 // First, use the broker "manually"
844 BPF_ASSERT(broker_process->Open("/proc/denied", O_RDONLY) == -EPERM);
845 BPF_ASSERT(broker_process->Access("/proc/denied", R_OK) == -EPERM);
846 BPF_ASSERT(broker_process->Open("/proc/allowed", O_RDONLY) == -ENOENT);
847 BPF_ASSERT(broker_process->Access("/proc/allowed", R_OK) == -ENOENT);
848
849 // Now use glibc's open() as an external library would.
850 BPF_ASSERT(open("/proc/denied", O_RDONLY) == -1);
851 BPF_ASSERT(errno == EPERM);
852
853 BPF_ASSERT(open("/proc/allowed", O_RDONLY) == -1);
854 BPF_ASSERT(errno == ENOENT);
855
856 // Also test glibc's openat(), some versions of libc use it transparently
857 // instead of open().
858 BPF_ASSERT(openat(AT_FDCWD, "/proc/denied", O_RDONLY) == -1);
859 BPF_ASSERT(errno == EPERM);
860
861 BPF_ASSERT(openat(AT_FDCWD, "/proc/allowed", O_RDONLY) == -1);
862 BPF_ASSERT(errno == ENOENT);
863
864 // And test glibc's access().
865 BPF_ASSERT(access("/proc/denied", R_OK) == -1);
866 BPF_ASSERT(errno == EPERM);
867
868 BPF_ASSERT(access("/proc/allowed", R_OK) == -1);
869 BPF_ASSERT(errno == ENOENT);
870
871 // This is also white listed and does exist.
872 int cpu_info_access = access("/proc/cpuinfo", R_OK);
873 BPF_ASSERT(cpu_info_access == 0);
874 int cpu_info_fd = open("/proc/cpuinfo", O_RDONLY);
875 BPF_ASSERT(cpu_info_fd >= 0);
876 char buf[1024];
877 BPF_ASSERT(read(cpu_info_fd, buf, sizeof(buf)) > 0);
878 }
879
880 // Simple test demonstrating how to use SandboxBPF::Cond() 734 // Simple test demonstrating how to use SandboxBPF::Cond()
881 735
882 class SimpleCondTestPolicy : public Policy { 736 class SimpleCondTestPolicy : public Policy {
883 public: 737 public:
884 SimpleCondTestPolicy() {} 738 SimpleCondTestPolicy() {}
885 ~SimpleCondTestPolicy() override {} 739 ~SimpleCondTestPolicy() override {}
886 740
887 ResultExpr EvaluateSyscall(int sysno) const override; 741 ResultExpr EvaluateSyscall(int sysno) const override;
888 742
889 private: 743 private:
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after
2390 BPF_ASSERT_EQ(ENOSYS, errno); 2244 BPF_ASSERT_EQ(ENOSYS, errno);
2391 2245
2392 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300)); 2246 BPF_ASSERT_EQ(-1, syscall(__NR_setgid, 300));
2393 BPF_ASSERT_EQ(EPERM, errno); 2247 BPF_ASSERT_EQ(EPERM, errno);
2394 } 2248 }
2395 2249
2396 } // namespace 2250 } // namespace
2397 2251
2398 } // namespace bpf_dsl 2252 } // namespace bpf_dsl
2399 } // namespace sandbox 2253 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/integration_tests/DEPS ('k') | sandbox/linux/integration_tests/namespace_unix_domain_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698