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"
12 #include <sys/prctl.h>
13 #include <sys/resource.h>
14 #include <sys/socket.h>
16 #include <sys/syscall.h>
18 #include <sys/types.h>
23 #include "base/files/scoped_file.h"
24 #include "base/macros.h"
25 #include "base/posix/eintr_wrapper.h"
26 #include "base/threading/thread.h"
27 #include "build/build_config.h"
28 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
29 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
30 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
31 #include "sandbox/linux/seccomp-bpf/syscall.h"
32 #include "sandbox/linux/services/syscall_wrappers.h"
33 #include "sandbox/linux/services/thread_helpers.h"
34 #include "sandbox/linux/system_headers/linux_futex.h"
35 #include "sandbox/linux/system_headers/linux_syscalls.h"
36 #include "sandbox/linux/tests/test_utils.h"
37 #include "sandbox/linux/tests/unit_tests.h"
43 // This also tests that read(), write() and fstat() are allowed.
44 void TestPipeOrSocketPair(base::ScopedFD read_end
, base::ScopedFD write_end
) {
45 BPF_ASSERT_LE(0, read_end
.get());
46 BPF_ASSERT_LE(0, write_end
.get());
48 int sys_ret
= fstat(read_end
.get(), &stat_buf
);
49 BPF_ASSERT_EQ(0, sys_ret
);
50 BPF_ASSERT(S_ISFIFO(stat_buf
.st_mode
) || S_ISSOCK(stat_buf
.st_mode
));
52 const ssize_t kTestTransferSize
= 4;
53 static const char kTestString
[kTestTransferSize
] = {'T', 'E', 'S', 'T'};
54 ssize_t transfered
= 0;
57 HANDLE_EINTR(write(write_end
.get(), kTestString
, kTestTransferSize
));
58 BPF_ASSERT_EQ(kTestTransferSize
, transfered
);
59 char read_buf
[kTestTransferSize
+ 1] = {0};
60 transfered
= HANDLE_EINTR(read(read_end
.get(), read_buf
, sizeof(read_buf
)));
61 BPF_ASSERT_EQ(kTestTransferSize
, transfered
);
62 BPF_ASSERT_EQ(0, memcmp(kTestString
, read_buf
, kTestTransferSize
));
65 // Test that a few easy-to-test system calls are allowed.
66 BPF_TEST_C(BaselinePolicy
, BaselinePolicyBasicAllowed
, BaselinePolicy
) {
67 BPF_ASSERT_EQ(0, sched_yield());
70 int sys_ret
= pipe(pipefd
);
71 BPF_ASSERT_EQ(0, sys_ret
);
72 TestPipeOrSocketPair(base::ScopedFD(pipefd
[0]), base::ScopedFD(pipefd
[1]));
74 BPF_ASSERT_LE(1, getpid());
75 BPF_ASSERT_LE(0, getuid());
78 BPF_TEST_C(BaselinePolicy
, FchmodErrno
, BaselinePolicy
) {
79 int ret
= fchmod(-1, 07777);
80 BPF_ASSERT_EQ(-1, ret
);
81 // Without the sandbox, this would EBADF instead.
82 BPF_ASSERT_EQ(EPERM
, errno
);
85 BPF_TEST_C(BaselinePolicy
, ForkErrno
, BaselinePolicy
) {
88 const int fork_errno
= errno
;
89 TestUtils::HandlePostForkReturn(pid
);
91 BPF_ASSERT_EQ(-1, pid
);
92 BPF_ASSERT_EQ(EPERM
, fork_errno
);
95 pid_t
ForkX86Glibc() {
97 return sys_clone(CLONE_PARENT_SETTID
| SIGCHLD
, nullptr, &ptid
, nullptr,
101 BPF_TEST_C(BaselinePolicy
, ForkX86Eperm
, BaselinePolicy
) {
103 pid_t pid
= ForkX86Glibc();
104 const int fork_errno
= errno
;
105 TestUtils::HandlePostForkReturn(pid
);
107 BPF_ASSERT_EQ(-1, pid
);
108 BPF_ASSERT_EQ(EPERM
, fork_errno
);
111 pid_t
ForkARMGlibc() {
113 return sys_clone(CLONE_CHILD_SETTID
| CLONE_CHILD_CLEARTID
| SIGCHLD
, nullptr,
114 nullptr, &ctid
, nullptr);
117 BPF_TEST_C(BaselinePolicy
, ForkArmEperm
, BaselinePolicy
) {
119 pid_t pid
= ForkARMGlibc();
120 const int fork_errno
= errno
;
121 TestUtils::HandlePostForkReturn(pid
);
123 BPF_ASSERT_EQ(-1, pid
);
124 BPF_ASSERT_EQ(EPERM
, fork_errno
);
127 BPF_TEST_C(BaselinePolicy
, CreateThread
, BaselinePolicy
) {
128 base::Thread
thread("sandbox_tests");
129 BPF_ASSERT(thread
.Start());
132 BPF_DEATH_TEST_C(BaselinePolicy
,
133 DisallowedCloneFlagCrashes
,
134 DEATH_SEGV_MESSAGE(GetCloneErrorMessageContentForTests()),
136 pid_t pid
= sys_clone(CLONE_THREAD
| SIGCHLD
);
137 TestUtils::HandlePostForkReturn(pid
);
140 BPF_DEATH_TEST_C(BaselinePolicy
,
141 DisallowedKillCrashes
,
142 DEATH_SEGV_MESSAGE(GetKillErrorMessageContentForTests()),
144 BPF_ASSERT_NE(1, getpid());
149 BPF_TEST_C(BaselinePolicy
, CanKillSelf
, BaselinePolicy
) {
150 int sys_ret
= kill(getpid(), 0);
151 BPF_ASSERT_EQ(0, sys_ret
);
154 BPF_TEST_C(BaselinePolicy
, Socketpair
, BaselinePolicy
) {
156 int sys_ret
= socketpair(AF_UNIX
, SOCK_DGRAM
, 0, sv
);
157 BPF_ASSERT_EQ(0, sys_ret
);
158 TestPipeOrSocketPair(base::ScopedFD(sv
[0]), base::ScopedFD(sv
[1]));
160 sys_ret
= socketpair(AF_UNIX
, SOCK_SEQPACKET
, 0, sv
);
161 BPF_ASSERT_EQ(0, sys_ret
);
162 TestPipeOrSocketPair(base::ScopedFD(sv
[0]), base::ScopedFD(sv
[1]));
165 // Not all architectures can restrict the domain for socketpair().
166 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
167 BPF_DEATH_TEST_C(BaselinePolicy
,
168 SocketpairWrongDomain
,
169 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
172 ignore_result(socketpair(AF_INET
, SOCK_STREAM
, 0, sv
));
175 #endif // defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
177 BPF_TEST_C(BaselinePolicy
, EPERM_open
, BaselinePolicy
) {
179 int sys_ret
= open("/proc/cpuinfo", O_RDONLY
);
180 BPF_ASSERT_EQ(-1, sys_ret
);
181 BPF_ASSERT_EQ(EPERM
, errno
);
184 BPF_TEST_C(BaselinePolicy
, EPERM_access
, BaselinePolicy
) {
186 int sys_ret
= access("/proc/cpuinfo", R_OK
);
187 BPF_ASSERT_EQ(-1, sys_ret
);
188 BPF_ASSERT_EQ(EPERM
, errno
);
191 BPF_TEST_C(BaselinePolicy
, EPERM_getcwd
, BaselinePolicy
) {
194 char* cwd
= getcwd(buf
, sizeof(buf
));
195 BPF_ASSERT_EQ(NULL
, cwd
);
196 BPF_ASSERT_EQ(EPERM
, errno
);
199 BPF_DEATH_TEST_C(BaselinePolicy
,
200 SIGSYS_InvalidSyscall
,
201 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
203 Syscall::InvalidCall();
206 // A failing test using this macro could be problematic since we perform
207 // system calls by passing "0" as every argument.
208 // The kernel could SIGSEGV the process or the system call itself could reboot
209 // the machine. Some thoughts have been given when hand-picking the system
210 // calls below to limit any potential side effects outside of the current
212 #define TEST_BASELINE_SIGSYS(sysno) \
213 BPF_DEATH_TEST_C(BaselinePolicy, \
215 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), \
217 syscall(sysno, 0, 0, 0, 0, 0, 0); \
221 TEST_BASELINE_SIGSYS(__NR_acct
);
222 TEST_BASELINE_SIGSYS(__NR_chroot
);
223 TEST_BASELINE_SIGSYS(__NR_fanotify_init
);
224 TEST_BASELINE_SIGSYS(__NR_fgetxattr
);
225 TEST_BASELINE_SIGSYS(__NR_getcpu
);
226 TEST_BASELINE_SIGSYS(__NR_getitimer
);
227 TEST_BASELINE_SIGSYS(__NR_init_module
);
228 TEST_BASELINE_SIGSYS(__NR_io_cancel
);
229 TEST_BASELINE_SIGSYS(__NR_keyctl
);
230 TEST_BASELINE_SIGSYS(__NR_mq_open
);
231 TEST_BASELINE_SIGSYS(__NR_ptrace
);
232 TEST_BASELINE_SIGSYS(__NR_sched_setaffinity
);
233 TEST_BASELINE_SIGSYS(__NR_setpgid
);
234 TEST_BASELINE_SIGSYS(__NR_swapon
);
235 TEST_BASELINE_SIGSYS(__NR_sysinfo
);
236 TEST_BASELINE_SIGSYS(__NR_syslog
);
237 TEST_BASELINE_SIGSYS(__NR_timer_create
);
239 #if !defined(__aarch64__)
240 TEST_BASELINE_SIGSYS(__NR_eventfd
);
241 TEST_BASELINE_SIGSYS(__NR_inotify_init
);
242 TEST_BASELINE_SIGSYS(__NR_vserver
);
245 BPF_DEATH_TEST_C(BaselinePolicy
,
246 FutexWithRequeuePriorityInheritence
,
247 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
249 syscall(__NR_futex
, NULL
, FUTEX_CMP_REQUEUE_PI
, 0, NULL
, NULL
, 0);
253 BPF_DEATH_TEST_C(BaselinePolicy
,
254 FutexWithRequeuePriorityInheritencePrivate
,
255 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
257 syscall(__NR_futex
, NULL
, FUTEX_CMP_REQUEUE_PI_PRIVATE
, 0, NULL
, NULL
, 0);
261 BPF_DEATH_TEST_C(BaselinePolicy
,
262 FutexWithUnlockPIPrivate
,
263 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
265 syscall(__NR_futex
, NULL
, FUTEX_UNLOCK_PI_PRIVATE
, 0, NULL
, NULL
, 0);
269 BPF_TEST_C(BaselinePolicy
, PrctlDumpable
, BaselinePolicy
) {
270 const int is_dumpable
= prctl(PR_GET_DUMPABLE
, 0, 0, 0, 0);
271 BPF_ASSERT(is_dumpable
== 1 || is_dumpable
== 0);
272 const int prctl_ret
= prctl(PR_SET_DUMPABLE
, is_dumpable
, 0, 0, 0, 0);
273 BPF_ASSERT_EQ(0, prctl_ret
);
276 // Workaround incomplete Android headers.
277 #if !defined(PR_CAPBSET_READ)
278 #define PR_CAPBSET_READ 23
281 BPF_DEATH_TEST_C(BaselinePolicy
,
283 DEATH_SEGV_MESSAGE(GetPrctlErrorMessageContentForTests()),
285 prctl(PR_CAPBSET_READ
, 0, 0, 0, 0);
289 BPF_TEST_C(BaselinePolicy
, GetOrSetPriority
, BaselinePolicy
) {
291 const int original_prio
= getpriority(PRIO_PROCESS
, 0);
292 // Check errno instead of the return value since this system call can return
293 // -1 as a valid value.
294 BPF_ASSERT_EQ(0, errno
);
297 int rc
= getpriority(PRIO_PROCESS
, getpid());
298 BPF_ASSERT_EQ(0, errno
);
300 rc
= getpriority(PRIO_PROCESS
, getpid() + 1);
301 BPF_ASSERT_EQ(-1, rc
);
302 BPF_ASSERT_EQ(EPERM
, errno
);
304 rc
= setpriority(PRIO_PROCESS
, 0, original_prio
);
305 BPF_ASSERT_EQ(0, rc
);
307 rc
= setpriority(PRIO_PROCESS
, getpid(), original_prio
);
308 BPF_ASSERT_EQ(0, rc
);
311 rc
= setpriority(PRIO_PROCESS
, getpid() + 1, original_prio
);
312 BPF_ASSERT_EQ(-1, rc
);
313 BPF_ASSERT_EQ(EPERM
, errno
);
316 BPF_DEATH_TEST_C(BaselinePolicy
,
318 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
320 getpriority(PRIO_USER
, 0);
324 BPF_DEATH_TEST_C(BaselinePolicy
,
325 ClockGettimeWithDisallowedClockCrashes
,
326 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
329 clock_gettime(CLOCK_MONOTONIC_RAW
, &ts
);
334 } // namespace sandbox