Fix crash on app list start page keyboard navigation with <4 apps.
[chromium-blink-merge.git] / sandbox / linux / seccomp-bpf-helpers / baseline_policy_unittest.cc
blobe6e893493a3a05fe7eb75e5379ef44d4cf77c285
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
3 // found in the LICENSE file.
5 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <linux/futex.h>
10 #include <sched.h>
11 #include <signal.h>
12 #include <string.h>
13 #include <sys/prctl.h>
14 #include <sys/resource.h>
15 #include <sys/socket.h>
16 #include <sys/stat.h>
17 #include <sys/syscall.h>
18 #include <sys/time.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include <time.h>
22 #include <unistd.h>
24 #include "base/files/scoped_file.h"
25 #include "base/macros.h"
26 #include "base/posix/eintr_wrapper.h"
27 #include "base/threading/thread.h"
28 #include "build/build_config.h"
29 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
30 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
31 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
32 #include "sandbox/linux/seccomp-bpf/syscall.h"
33 #include "sandbox/linux/services/syscall_wrappers.h"
34 #include "sandbox/linux/services/thread_helpers.h"
35 #include "sandbox/linux/system_headers/android_futex.h"
36 #include "sandbox/linux/system_headers/linux_syscalls.h"
37 #include "sandbox/linux/tests/test_utils.h"
38 #include "sandbox/linux/tests/unit_tests.h"
40 namespace sandbox {
42 namespace {
44 // This also tests that read(), write() and fstat() are allowed.
45 void TestPipeOrSocketPair(base::ScopedFD read_end, base::ScopedFD write_end) {
46 BPF_ASSERT_LE(0, read_end.get());
47 BPF_ASSERT_LE(0, write_end.get());
48 struct stat stat_buf;
49 int sys_ret = fstat(read_end.get(), &stat_buf);
50 BPF_ASSERT_EQ(0, sys_ret);
51 BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode));
53 const ssize_t kTestTransferSize = 4;
54 static const char kTestString[kTestTransferSize] = {'T', 'E', 'S', 'T'};
55 ssize_t transfered = 0;
57 transfered =
58 HANDLE_EINTR(write(write_end.get(), kTestString, kTestTransferSize));
59 BPF_ASSERT_EQ(kTestTransferSize, transfered);
60 char read_buf[kTestTransferSize + 1] = {0};
61 transfered = HANDLE_EINTR(read(read_end.get(), read_buf, sizeof(read_buf)));
62 BPF_ASSERT_EQ(kTestTransferSize, transfered);
63 BPF_ASSERT_EQ(0, memcmp(kTestString, read_buf, kTestTransferSize));
66 // Test that a few easy-to-test system calls are allowed.
67 BPF_TEST_C(BaselinePolicy, BaselinePolicyBasicAllowed, BaselinePolicy) {
68 BPF_ASSERT_EQ(0, sched_yield());
70 int pipefd[2];
71 int sys_ret = pipe(pipefd);
72 BPF_ASSERT_EQ(0, sys_ret);
73 TestPipeOrSocketPair(base::ScopedFD(pipefd[0]), base::ScopedFD(pipefd[1]));
75 BPF_ASSERT_LE(1, getpid());
76 BPF_ASSERT_LE(0, getuid());
79 BPF_TEST_C(BaselinePolicy, FchmodErrno, BaselinePolicy) {
80 int ret = fchmod(-1, 07777);
81 BPF_ASSERT_EQ(-1, ret);
82 // Without the sandbox, this would EBADF instead.
83 BPF_ASSERT_EQ(EPERM, errno);
86 BPF_TEST_C(BaselinePolicy, ForkErrno, BaselinePolicy) {
87 errno = 0;
88 pid_t pid = fork();
89 const int fork_errno = errno;
90 TestUtils::HandlePostForkReturn(pid);
92 BPF_ASSERT_EQ(-1, pid);
93 BPF_ASSERT_EQ(EPERM, fork_errno);
96 pid_t ForkX86Glibc() {
97 static pid_t ptid;
98 return sys_clone(CLONE_PARENT_SETTID | SIGCHLD, nullptr, &ptid, nullptr,
99 nullptr);
102 BPF_TEST_C(BaselinePolicy, ForkX86Eperm, BaselinePolicy) {
103 errno = 0;
104 pid_t pid = ForkX86Glibc();
105 const int fork_errno = errno;
106 TestUtils::HandlePostForkReturn(pid);
108 BPF_ASSERT_EQ(-1, pid);
109 BPF_ASSERT_EQ(EPERM, fork_errno);
112 pid_t ForkARMGlibc() {
113 static pid_t ctid;
114 return sys_clone(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, nullptr,
115 nullptr, &ctid, nullptr);
118 BPF_TEST_C(BaselinePolicy, ForkArmEperm, BaselinePolicy) {
119 errno = 0;
120 pid_t pid = ForkARMGlibc();
121 const int fork_errno = errno;
122 TestUtils::HandlePostForkReturn(pid);
124 BPF_ASSERT_EQ(-1, pid);
125 BPF_ASSERT_EQ(EPERM, fork_errno);
128 BPF_TEST_C(BaselinePolicy, CreateThread, BaselinePolicy) {
129 base::Thread thread("sandbox_tests");
130 BPF_ASSERT(thread.Start());
133 BPF_DEATH_TEST_C(BaselinePolicy,
134 DisallowedCloneFlagCrashes,
135 DEATH_SEGV_MESSAGE(GetCloneErrorMessageContentForTests()),
136 BaselinePolicy) {
137 pid_t pid = sys_clone(CLONE_THREAD | SIGCHLD);
138 TestUtils::HandlePostForkReturn(pid);
141 BPF_DEATH_TEST_C(BaselinePolicy,
142 DisallowedKillCrashes,
143 DEATH_SEGV_MESSAGE(GetKillErrorMessageContentForTests()),
144 BaselinePolicy) {
145 BPF_ASSERT_NE(1, getpid());
146 kill(1, 0);
147 _exit(0);
150 BPF_TEST_C(BaselinePolicy, CanKillSelf, BaselinePolicy) {
151 int sys_ret = kill(getpid(), 0);
152 BPF_ASSERT_EQ(0, sys_ret);
155 BPF_TEST_C(BaselinePolicy, Socketpair, BaselinePolicy) {
156 int sv[2];
157 int sys_ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv);
158 BPF_ASSERT_EQ(0, sys_ret);
159 TestPipeOrSocketPair(base::ScopedFD(sv[0]), base::ScopedFD(sv[1]));
161 sys_ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv);
162 BPF_ASSERT_EQ(0, sys_ret);
163 TestPipeOrSocketPair(base::ScopedFD(sv[0]), base::ScopedFD(sv[1]));
166 // Not all architectures can restrict the domain for socketpair().
167 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
168 BPF_DEATH_TEST_C(BaselinePolicy,
169 SocketpairWrongDomain,
170 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
171 BaselinePolicy) {
172 int sv[2];
173 ignore_result(socketpair(AF_INET, SOCK_STREAM, 0, sv));
174 _exit(1);
176 #endif // defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
178 BPF_TEST_C(BaselinePolicy, EPERM_open, BaselinePolicy) {
179 errno = 0;
180 int sys_ret = open("/proc/cpuinfo", O_RDONLY);
181 BPF_ASSERT_EQ(-1, sys_ret);
182 BPF_ASSERT_EQ(EPERM, errno);
185 BPF_TEST_C(BaselinePolicy, EPERM_access, BaselinePolicy) {
186 errno = 0;
187 int sys_ret = access("/proc/cpuinfo", R_OK);
188 BPF_ASSERT_EQ(-1, sys_ret);
189 BPF_ASSERT_EQ(EPERM, errno);
192 BPF_TEST_C(BaselinePolicy, EPERM_getcwd, BaselinePolicy) {
193 errno = 0;
194 char buf[1024];
195 char* cwd = getcwd(buf, sizeof(buf));
196 BPF_ASSERT_EQ(NULL, cwd);
197 BPF_ASSERT_EQ(EPERM, errno);
200 BPF_DEATH_TEST_C(BaselinePolicy,
201 SIGSYS_InvalidSyscall,
202 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
203 BaselinePolicy) {
204 Syscall::InvalidCall();
207 // A failing test using this macro could be problematic since we perform
208 // system calls by passing "0" as every argument.
209 // The kernel could SIGSEGV the process or the system call itself could reboot
210 // the machine. Some thoughts have been given when hand-picking the system
211 // calls below to limit any potential side effects outside of the current
212 // process.
213 #define TEST_BASELINE_SIGSYS(sysno) \
214 BPF_DEATH_TEST_C(BaselinePolicy, \
215 SIGSYS_##sysno, \
216 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), \
217 BaselinePolicy) { \
218 syscall(sysno, 0, 0, 0, 0, 0, 0); \
219 _exit(1); \
222 TEST_BASELINE_SIGSYS(__NR_acct);
223 TEST_BASELINE_SIGSYS(__NR_chroot);
224 TEST_BASELINE_SIGSYS(__NR_fanotify_init);
225 TEST_BASELINE_SIGSYS(__NR_fgetxattr);
226 TEST_BASELINE_SIGSYS(__NR_getcpu);
227 TEST_BASELINE_SIGSYS(__NR_getitimer);
228 TEST_BASELINE_SIGSYS(__NR_init_module);
229 TEST_BASELINE_SIGSYS(__NR_io_cancel);
230 TEST_BASELINE_SIGSYS(__NR_keyctl);
231 TEST_BASELINE_SIGSYS(__NR_mq_open);
232 TEST_BASELINE_SIGSYS(__NR_ptrace);
233 TEST_BASELINE_SIGSYS(__NR_sched_setaffinity);
234 TEST_BASELINE_SIGSYS(__NR_setpgid);
235 TEST_BASELINE_SIGSYS(__NR_swapon);
236 TEST_BASELINE_SIGSYS(__NR_sysinfo);
237 TEST_BASELINE_SIGSYS(__NR_syslog);
238 TEST_BASELINE_SIGSYS(__NR_timer_create);
240 #if !defined(__aarch64__)
241 TEST_BASELINE_SIGSYS(__NR_eventfd);
242 TEST_BASELINE_SIGSYS(__NR_inotify_init);
243 TEST_BASELINE_SIGSYS(__NR_vserver);
244 #endif
246 BPF_DEATH_TEST_C(BaselinePolicy,
247 FutexWithRequeuePriorityInheritence,
248 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
249 BaselinePolicy) {
250 syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI, 0, NULL, NULL, 0);
251 _exit(1);
254 BPF_DEATH_TEST_C(BaselinePolicy,
255 FutexWithRequeuePriorityInheritencePrivate,
256 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
257 BaselinePolicy) {
258 syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI_PRIVATE, 0, NULL, NULL, 0);
259 _exit(1);
262 BPF_DEATH_TEST_C(BaselinePolicy,
263 FutexWithUnlockPIPrivate,
264 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
265 BaselinePolicy) {
266 syscall(__NR_futex, NULL, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0);
267 _exit(1);
270 BPF_TEST_C(BaselinePolicy, PrctlDumpable, BaselinePolicy) {
271 const int is_dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
272 BPF_ASSERT(is_dumpable == 1 || is_dumpable == 0);
273 const int prctl_ret = prctl(PR_SET_DUMPABLE, is_dumpable, 0, 0, 0, 0);
274 BPF_ASSERT_EQ(0, prctl_ret);
277 // Workaround incomplete Android headers.
278 #if !defined(PR_CAPBSET_READ)
279 #define PR_CAPBSET_READ 23
280 #endif
282 BPF_DEATH_TEST_C(BaselinePolicy,
283 PrctlSigsys,
284 DEATH_SEGV_MESSAGE(GetPrctlErrorMessageContentForTests()),
285 BaselinePolicy) {
286 prctl(PR_CAPBSET_READ, 0, 0, 0, 0);
287 _exit(1);
290 BPF_TEST_C(BaselinePolicy, GetOrSetPriority, BaselinePolicy) {
291 errno = 0;
292 const int original_prio = getpriority(PRIO_PROCESS, 0);
293 // Check errno instead of the return value since this system call can return
294 // -1 as a valid value.
295 BPF_ASSERT_EQ(0, errno);
297 errno = 0;
298 int rc = getpriority(PRIO_PROCESS, getpid());
299 BPF_ASSERT_EQ(0, errno);
301 rc = getpriority(PRIO_PROCESS, getpid() + 1);
302 BPF_ASSERT_EQ(-1, rc);
303 BPF_ASSERT_EQ(EPERM, errno);
305 rc = setpriority(PRIO_PROCESS, 0, original_prio);
306 BPF_ASSERT_EQ(0, rc);
308 rc = setpriority(PRIO_PROCESS, getpid(), original_prio);
309 BPF_ASSERT_EQ(0, rc);
311 errno = 0;
312 rc = setpriority(PRIO_PROCESS, getpid() + 1, original_prio);
313 BPF_ASSERT_EQ(-1, rc);
314 BPF_ASSERT_EQ(EPERM, errno);
317 BPF_DEATH_TEST_C(BaselinePolicy,
318 GetPrioritySigsys,
319 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
320 BaselinePolicy) {
321 getpriority(PRIO_USER, 0);
322 _exit(1);
325 BPF_DEATH_TEST_C(BaselinePolicy,
326 ClockGettimeWithDisallowedClockCrashes,
327 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
328 BaselinePolicy) {
329 struct timespec ts;
330 clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
333 } // namespace
335 } // namespace sandbox