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"
9 #include <linux/futex.h>
13 #include <sys/prctl.h>
14 #include <sys/resource.h>
15 #include <sys/socket.h>
17 #include <sys/syscall.h>
19 #include <sys/types.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"
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());
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;
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());
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
) {
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() {
98 return sys_clone(CLONE_PARENT_SETTID
| SIGCHLD
, nullptr, &ptid
, nullptr,
102 BPF_TEST_C(BaselinePolicy
, ForkX86Eperm
, BaselinePolicy
) {
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() {
114 return sys_clone(CLONE_CHILD_SETTID
| CLONE_CHILD_CLEARTID
| SIGCHLD
, nullptr,
115 nullptr, &ctid
, nullptr);
118 BPF_TEST_C(BaselinePolicy
, ForkArmEperm
, BaselinePolicy
) {
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()),
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()),
145 BPF_ASSERT_NE(1, getpid());
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
) {
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()),
173 ignore_result(socketpair(AF_INET
, SOCK_STREAM
, 0, sv
));
176 #endif // defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
178 BPF_TEST_C(BaselinePolicy
, EPERM_open
, BaselinePolicy
) {
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
) {
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
) {
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()),
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
213 #define TEST_BASELINE_SIGSYS(sysno) \
214 BPF_DEATH_TEST_C(BaselinePolicy, \
216 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()), \
218 syscall(sysno, 0, 0, 0, 0, 0, 0); \
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
);
246 BPF_DEATH_TEST_C(BaselinePolicy
,
247 FutexWithRequeuePriorityInheritence
,
248 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
250 syscall(__NR_futex
, NULL
, FUTEX_CMP_REQUEUE_PI
, 0, NULL
, NULL
, 0);
254 BPF_DEATH_TEST_C(BaselinePolicy
,
255 FutexWithRequeuePriorityInheritencePrivate
,
256 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
258 syscall(__NR_futex
, NULL
, FUTEX_CMP_REQUEUE_PI_PRIVATE
, 0, NULL
, NULL
, 0);
262 BPF_DEATH_TEST_C(BaselinePolicy
,
263 FutexWithUnlockPIPrivate
,
264 DEATH_SEGV_MESSAGE(GetFutexErrorMessageContentForTests()),
266 syscall(__NR_futex
, NULL
, FUTEX_UNLOCK_PI_PRIVATE
, 0, NULL
, NULL
, 0);
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
282 BPF_DEATH_TEST_C(BaselinePolicy
,
284 DEATH_SEGV_MESSAGE(GetPrctlErrorMessageContentForTests()),
286 prctl(PR_CAPBSET_READ
, 0, 0, 0, 0);
290 BPF_TEST_C(BaselinePolicy
, GetOrSetPriority
, BaselinePolicy
) {
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
);
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
);
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
,
319 DEATH_SEGV_MESSAGE(GetErrorMessageContentForTests()),
321 getpriority(PRIO_USER
, 0);
325 BPF_DEATH_TEST_C(BaselinePolicy
,
326 ClockGettimeWithDisallowedClockCrashes
,
327 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
330 clock_gettime(CLOCK_MONOTONIC_RAW
, &ts
);
335 } // namespace sandbox