OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/seccomp-bpf-helpers/baseline_policy.h" | 5 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <linux/futex.h> | 9 #include <linux/futex.h> |
10 #include <sched.h> | 10 #include <sched.h> |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "base/macros.h" | 25 #include "base/macros.h" |
26 #include "base/posix/eintr_wrapper.h" | 26 #include "base/posix/eintr_wrapper.h" |
27 #include "base/threading/thread.h" | 27 #include "base/threading/thread.h" |
28 #include "build/build_config.h" | 28 #include "build/build_config.h" |
29 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" | 29 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" |
30 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" | 30 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" |
31 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 31 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
32 #include "sandbox/linux/seccomp-bpf/syscall.h" | 32 #include "sandbox/linux/seccomp-bpf/syscall.h" |
33 #include "sandbox/linux/services/android_futex.h" | 33 #include "sandbox/linux/services/android_futex.h" |
34 #include "sandbox/linux/services/linux_syscalls.h" | 34 #include "sandbox/linux/services/linux_syscalls.h" |
| 35 #include "sandbox/linux/services/syscall_wrappers.h" |
35 #include "sandbox/linux/services/thread_helpers.h" | 36 #include "sandbox/linux/services/thread_helpers.h" |
| 37 #include "sandbox/linux/tests/test_utils.h" |
36 #include "sandbox/linux/tests/unit_tests.h" | 38 #include "sandbox/linux/tests/unit_tests.h" |
37 | 39 |
38 namespace sandbox { | 40 namespace sandbox { |
39 | 41 |
40 namespace { | 42 namespace { |
41 | 43 |
42 // |pid| is the return value of a fork()-like call. This | |
43 // makes sure that if fork() succeeded the child exits | |
44 // and the parent waits for it. | |
45 void HandlePostForkReturn(pid_t pid) { | |
46 const int kChildExitCode = 1; | |
47 if (pid > 0) { | |
48 int status = 0; | |
49 PCHECK(pid == HANDLE_EINTR(waitpid(pid, &status, 0))); | |
50 CHECK(WIFEXITED(status)); | |
51 CHECK_EQ(kChildExitCode, WEXITSTATUS(status)); | |
52 } else if (pid == 0) { | |
53 _exit(kChildExitCode); | |
54 } | |
55 } | |
56 | |
57 // Check that HandlePostForkReturn works. | |
58 TEST(BaselinePolicy, HandlePostForkReturn) { | |
59 pid_t pid = fork(); | |
60 HandlePostForkReturn(pid); | |
61 } | |
62 | |
63 // This also tests that read(), write() and fstat() are allowed. | 44 // This also tests that read(), write() and fstat() are allowed. |
64 void TestPipeOrSocketPair(base::ScopedFD read_end, base::ScopedFD write_end) { | 45 void TestPipeOrSocketPair(base::ScopedFD read_end, base::ScopedFD write_end) { |
65 BPF_ASSERT_LE(0, read_end.get()); | 46 BPF_ASSERT_LE(0, read_end.get()); |
66 BPF_ASSERT_LE(0, write_end.get()); | 47 BPF_ASSERT_LE(0, write_end.get()); |
67 struct stat stat_buf; | 48 struct stat stat_buf; |
68 int sys_ret = fstat(read_end.get(), &stat_buf); | 49 int sys_ret = fstat(read_end.get(), &stat_buf); |
69 BPF_ASSERT_EQ(0, sys_ret); | 50 BPF_ASSERT_EQ(0, sys_ret); |
70 BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode)); | 51 BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode)); |
71 | 52 |
72 const ssize_t kTestTransferSize = 4; | 53 const ssize_t kTestTransferSize = 4; |
(...skipping 26 matching lines...) Expand all Loading... |
99 int ret = fchmod(-1, 07777); | 80 int ret = fchmod(-1, 07777); |
100 BPF_ASSERT_EQ(-1, ret); | 81 BPF_ASSERT_EQ(-1, ret); |
101 // Without the sandbox, this would EBADF instead. | 82 // Without the sandbox, this would EBADF instead. |
102 BPF_ASSERT_EQ(EPERM, errno); | 83 BPF_ASSERT_EQ(EPERM, errno); |
103 } | 84 } |
104 | 85 |
105 BPF_TEST_C(BaselinePolicy, ForkErrno, BaselinePolicy) { | 86 BPF_TEST_C(BaselinePolicy, ForkErrno, BaselinePolicy) { |
106 errno = 0; | 87 errno = 0; |
107 pid_t pid = fork(); | 88 pid_t pid = fork(); |
108 const int fork_errno = errno; | 89 const int fork_errno = errno; |
109 HandlePostForkReturn(pid); | 90 TestUtils::HandlePostForkReturn(pid); |
110 | 91 |
111 BPF_ASSERT_EQ(-1, pid); | 92 BPF_ASSERT_EQ(-1, pid); |
112 BPF_ASSERT_EQ(EPERM, fork_errno); | 93 BPF_ASSERT_EQ(EPERM, fork_errno); |
113 } | 94 } |
114 | 95 |
115 pid_t ForkX86Glibc() { | 96 pid_t ForkX86Glibc() { |
116 return syscall(__NR_clone, CLONE_PARENT_SETTID | SIGCHLD); | 97 static pid_t ptid; |
| 98 return sys_clone(CLONE_PARENT_SETTID | SIGCHLD, nullptr, &ptid, nullptr, |
| 99 nullptr); |
117 } | 100 } |
118 | 101 |
119 BPF_TEST_C(BaselinePolicy, ForkX86Eperm, BaselinePolicy) { | 102 BPF_TEST_C(BaselinePolicy, ForkX86Eperm, BaselinePolicy) { |
120 errno = 0; | 103 errno = 0; |
121 pid_t pid = ForkX86Glibc(); | 104 pid_t pid = ForkX86Glibc(); |
122 const int fork_errno = errno; | 105 const int fork_errno = errno; |
123 HandlePostForkReturn(pid); | 106 TestUtils::HandlePostForkReturn(pid); |
124 | 107 |
125 BPF_ASSERT_EQ(-1, pid); | 108 BPF_ASSERT_EQ(-1, pid); |
126 BPF_ASSERT_EQ(EPERM, fork_errno); | 109 BPF_ASSERT_EQ(EPERM, fork_errno); |
127 } | 110 } |
128 | 111 |
129 pid_t ForkARMGlibc() { | 112 pid_t ForkARMGlibc() { |
130 return syscall(__NR_clone, | 113 static pid_t ctid; |
131 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD); | 114 return sys_clone(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, nullptr, |
| 115 nullptr, &ctid, nullptr); |
132 } | 116 } |
133 | 117 |
134 BPF_TEST_C(BaselinePolicy, ForkArmEperm, BaselinePolicy) { | 118 BPF_TEST_C(BaselinePolicy, ForkArmEperm, BaselinePolicy) { |
135 errno = 0; | 119 errno = 0; |
136 pid_t pid = ForkARMGlibc(); | 120 pid_t pid = ForkARMGlibc(); |
137 const int fork_errno = errno; | 121 const int fork_errno = errno; |
138 HandlePostForkReturn(pid); | 122 TestUtils::HandlePostForkReturn(pid); |
139 | 123 |
140 BPF_ASSERT_EQ(-1, pid); | 124 BPF_ASSERT_EQ(-1, pid); |
141 BPF_ASSERT_EQ(EPERM, fork_errno); | 125 BPF_ASSERT_EQ(EPERM, fork_errno); |
142 } | 126 } |
143 | 127 |
144 BPF_TEST_C(BaselinePolicy, CreateThread, BaselinePolicy) { | 128 BPF_TEST_C(BaselinePolicy, CreateThread, BaselinePolicy) { |
145 base::Thread thread("sandbox_tests"); | 129 base::Thread thread("sandbox_tests"); |
146 BPF_ASSERT(thread.Start()); | 130 BPF_ASSERT(thread.Start()); |
147 } | 131 } |
148 | 132 |
149 BPF_DEATH_TEST_C(BaselinePolicy, | 133 BPF_DEATH_TEST_C(BaselinePolicy, |
150 DisallowedCloneFlagCrashes, | 134 DisallowedCloneFlagCrashes, |
151 DEATH_SEGV_MESSAGE(GetCloneErrorMessageContentForTests()), | 135 DEATH_SEGV_MESSAGE(GetCloneErrorMessageContentForTests()), |
152 BaselinePolicy) { | 136 BaselinePolicy) { |
153 pid_t pid = syscall(__NR_clone, CLONE_THREAD | SIGCHLD); | 137 pid_t pid = sys_clone(CLONE_THREAD | SIGCHLD); |
154 HandlePostForkReturn(pid); | 138 TestUtils::HandlePostForkReturn(pid); |
155 } | 139 } |
156 | 140 |
157 BPF_DEATH_TEST_C(BaselinePolicy, | 141 BPF_DEATH_TEST_C(BaselinePolicy, |
158 DisallowedKillCrashes, | 142 DisallowedKillCrashes, |
159 DEATH_SEGV_MESSAGE(GetKillErrorMessageContentForTests()), | 143 DEATH_SEGV_MESSAGE(GetKillErrorMessageContentForTests()), |
160 BaselinePolicy) { | 144 BaselinePolicy) { |
161 BPF_ASSERT_NE(1, getpid()); | 145 BPF_ASSERT_NE(1, getpid()); |
162 kill(1, 0); | 146 kill(1, 0); |
163 _exit(0); | 147 _exit(0); |
164 } | 148 } |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 ClockGettimeWithDisallowedClockCrashes, | 326 ClockGettimeWithDisallowedClockCrashes, |
343 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), | 327 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), |
344 BaselinePolicy) { | 328 BaselinePolicy) { |
345 struct timespec ts; | 329 struct timespec ts; |
346 clock_gettime(CLOCK_MONOTONIC_RAW, &ts); | 330 clock_gettime(CLOCK_MONOTONIC_RAW, &ts); |
347 } | 331 } |
348 | 332 |
349 } // namespace | 333 } // namespace |
350 | 334 |
351 } // namespace sandbox | 335 } // namespace sandbox |
OLD | NEW |