Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / sandbox / linux / seccomp-bpf-helpers / baseline_policy_unittest.cc
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.
4
5 #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
6
7 #include <errno.h>
8 #include <sys/stat.h>
9 #include <sys/syscall.h>
10 #include <sys/types.h>
11 #include <sys/wait.h>
12 #include <unistd.h>
13
14 #include "base/posix/eintr_wrapper.h"
15 #include "base/threading/thread.h"
16 #include "build/build_config.h"
17 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
18 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
19 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
20 #include "sandbox/linux/services/linux_syscalls.h"
21 #include "sandbox/linux/services/thread_helpers.h"
22 #include "sandbox/linux/tests/unit_tests.h"
23
24 namespace sandbox {
25
26 namespace {
27
28 // |pid| is the return value of a fork()-like call. This
29 // makes sure that if fork() succeeded the child exits
30 // and the parent waits for it.
31 void HandlePostForkReturn(pid_t pid) {
32   const int kChildExitCode = 1;
33   if (pid > 0) {
34     int status = 0;
35     PCHECK(pid == HANDLE_EINTR(waitpid(pid, &status, 0)));
36     CHECK(WIFEXITED(status));
37     CHECK_EQ(kChildExitCode, WEXITSTATUS(status));
38   } else if (pid == 0) {
39     _exit(kChildExitCode);
40   }
41 }
42
43 // Check that HandlePostForkReturn works.
44 TEST(BaselinePolicy, HandlePostForkReturn) {
45   pid_t pid = fork();
46   HandlePostForkReturn(pid);
47 }
48
49 BPF_TEST_C(BaselinePolicy, FchmodErrno, BaselinePolicy) {
50   int ret = fchmod(-1, 07777);
51   BPF_ASSERT_EQ(-1, ret);
52   // Without the sandbox, this would EBADF instead.
53   BPF_ASSERT_EQ(EPERM, errno);
54 }
55
56 // TODO(jln): make this work with the sanitizers.
57 #if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
58
59 BPF_TEST_C(BaselinePolicy, ForkErrno, BaselinePolicy) {
60   errno = 0;
61   pid_t pid = fork();
62   const int fork_errno = errno;
63   HandlePostForkReturn(pid);
64
65   BPF_ASSERT_EQ(-1, pid);
66   BPF_ASSERT_EQ(EPERM, fork_errno);
67 }
68
69 pid_t ForkX86Glibc() {
70   return syscall(__NR_clone, CLONE_PARENT_SETTID | SIGCHLD);
71 }
72
73 BPF_TEST_C(BaselinePolicy, ForkX86Eperm, BaselinePolicy) {
74   errno = 0;
75   pid_t pid = ForkX86Glibc();
76   const int fork_errno = errno;
77   HandlePostForkReturn(pid);
78
79   BPF_ASSERT_EQ(-1, pid);
80   BPF_ASSERT_EQ(EPERM, fork_errno);
81 }
82
83 pid_t ForkARMGlibc() {
84   return syscall(__NR_clone,
85                  CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD);
86 }
87
88 BPF_TEST_C(BaselinePolicy, ForkArmEperm, BaselinePolicy) {
89   errno = 0;
90   pid_t pid = ForkARMGlibc();
91   const int fork_errno = errno;
92   HandlePostForkReturn(pid);
93
94   BPF_ASSERT_EQ(-1, pid);
95   BPF_ASSERT_EQ(EPERM, fork_errno);
96 }
97
98 BPF_TEST_C(BaselinePolicy, CreateThread, BaselinePolicy) {
99   base::Thread thread("sandbox_tests");
100   BPF_ASSERT(thread.Start());
101 }
102
103 BPF_DEATH_TEST_C(BaselinePolicy,
104                  DisallowedCloneFlagCrashes,
105                  DEATH_MESSAGE(GetCloneErrorMessageContentForTests()),
106                  BaselinePolicy) {
107   pid_t pid = syscall(__NR_clone, CLONE_THREAD | SIGCHLD);
108   HandlePostForkReturn(pid);
109 }
110
111 #endif  // !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
112
113 }  // namespace
114
115 }  // namespace sandbox