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 // Sanitizers internally use some syscalls which non-SFI NaCl disallows.
6 #if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \
7 !defined(MEMORY_SANITIZER) && !defined(LEAK_SANITIZER)
9 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h"
13 #include <linux/net.h>
20 #include <sys/prctl.h>
21 #include <sys/socket.h>
22 #include <sys/syscall.h>
23 #include <sys/types.h>
28 #include "base/at_exit.h"
29 #include "base/bind.h"
30 #include "base/callback.h"
31 #include "base/compiler_specific.h"
32 #include "base/files/scoped_file.h"
33 #include "base/logging.h"
34 #include "base/posix/eintr_wrapper.h"
35 #include "base/sys_info.h"
36 #include "base/threading/thread.h"
37 #include "base/time/time.h"
38 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
39 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
40 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
41 #include "sandbox/linux/seccomp-bpf/syscall.h"
42 #include "sandbox/linux/system_headers/linux_futex.h"
43 #include "sandbox/linux/system_headers/linux_signal.h"
44 #include "sandbox/linux/system_headers/linux_syscalls.h"
46 // These defines are for PNaCl toolchain build.
47 #if !defined(F_DUPFD_CLOEXEC)
48 #define F_DUPFD_CLOEXEC 1030
51 #if !defined(MAP_POPULATE)
52 #define MAP_POPULATE 0x8000
55 #if !defined(PROT_GROWSDOWN)
56 #define PROT_GROWSDOWN 0x01000000
59 #if !defined(CLOCK_MONOTONIC_RAW)
60 #define CLOCK_MONOTONIC_RAW 4
69 #if !defined(SYS_SOCKET)
73 #if !defined(SYS_BIND)
77 #if !defined(SYS_CONNECT)
81 #if !defined(SYS_LISTEN)
85 #if !defined(SYS_ACCEPT)
89 #if !defined(SYS_GETSOCKNAME)
90 #define SYS_GETSOCKNAME 6
93 #if !defined(SYS_GETPEERNAME)
94 #define SYS_GETPEERNAME 7
97 #if !defined(SYS_SETSOCKOPT)
98 #define SYS_SETSOCKOPT 14
101 #if !defined(SYS_GETSOCKOPT)
102 #define SYS_GETSOCKOPT 15
105 #endif // defined(__i386__)
109 void DoPipe(base::ScopedFD
* fds
) {
111 BPF_ASSERT_EQ(0, pipe(tmp_fds
));
112 fds
[0].reset(tmp_fds
[0]);
113 fds
[1].reset(tmp_fds
[1]);
116 void DoSocketpair(base::ScopedFD
* fds
) {
118 BPF_ASSERT_EQ(0, socketpair(AF_UNIX
, SOCK_STREAM
, 0, tmp_fds
));
119 fds
[0].reset(tmp_fds
[0]);
120 fds
[1].reset(tmp_fds
[1]);
123 TEST(NaClNonSfiSandboxTest
, BPFIsSupported
) {
124 bool seccomp_bpf_supported
= sandbox::SandboxBPF::SupportsSeccompSandbox(
125 sandbox::SandboxBPF::SeccompLevel::SINGLE_THREADED
);
127 if (!seccomp_bpf_supported
) {
128 LOG(ERROR
) << "Seccomp BPF is not supported, these tests "
129 << "will pass without running";
133 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
135 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
136 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
140 const int kExpectedValue
= 123;
142 void* SetValueInThread(void* test_val_ptr
) {
143 *reinterpret_cast<int*>(test_val_ptr
) = kExpectedValue
;
147 // To make this test pass, we need to allow sched_getaffinity and
148 // mmap. We just disable this test not to complicate the sandbox.
149 BPF_TEST_C(NaClNonSfiSandboxTest
,
150 clone_by_pthread_create
,
151 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
152 // clone call for thread creation is allowed.
155 BPF_ASSERT_EQ(0, pthread_create(&th
, NULL
, &SetValueInThread
, &test_val
));
156 BPF_ASSERT_EQ(0, pthread_join(th
, NULL
));
157 BPF_ASSERT_EQ(kExpectedValue
, test_val
);
161 // Call clone() to do a fork().
162 const int pid
= syscall(__NR_clone
, LINUX_SIGCHLD
, NULL
);
168 // The sanity check for DoFork without the sandbox.
169 TEST(NaClNonSfiSandboxTest
, DoFork
) {
170 const int pid
= DoFork();
173 ASSERT_EQ(pid
, HANDLE_EINTR(waitpid(pid
, &status
, 0)));
174 ASSERT_TRUE(WIFEXITED(status
));
175 ASSERT_EQ(0, WEXITSTATUS(status
));
178 // Then, try this in the sandbox.
179 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
182 sandbox::GetCloneErrorMessageContentForTests()),
183 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
187 BPF_TEST_C(NaClNonSfiSandboxTest
,
189 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
191 BPF_ASSERT_EQ(-1, syscall(__NR_prctl
, PR_SET_NAME
, "foo"));
192 BPF_ASSERT_EQ(EPERM
, errno
);
195 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
198 sandbox::GetPrctlErrorMessageContentForTests()),
199 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
200 syscall(__NR_prctl
, PR_SET_DUMPABLE
, 1UL);
203 #if defined(OS_NACL_NONSFI)
204 BPF_DEATH_TEST_C(NaClNonsfiSandboxTest
,
205 socketpair_af_unix_disallowed
,
206 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
207 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
209 socketpair(AF_UNIX
, SOCK_STREAM
, 0, tmp_fds
);
212 BPF_TEST_C(NaClNonSfiSandboxTest
,
214 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
215 base::ScopedFD fds
[2];
216 struct msghdr msg
= {};
218 std::string
payload("foo");
219 iov
.iov_base
= &payload
[0];
220 iov
.iov_len
= payload
.size();
224 BPF_ASSERT_EQ(static_cast<int>(payload
.size()),
225 HANDLE_EINTR(sendmsg(fds
[1].get(), &msg
, 0)));
226 BPF_ASSERT_EQ(static_cast<int>(payload
.size()),
227 HANDLE_EINTR(recvmsg(fds
[0].get(), &msg
, 0)));
228 BPF_ASSERT_EQ(0, shutdown(fds
[0].get(), SHUT_RDWR
));
232 // On arm and x86_64 the arguments to socketpair are passed in registers,
233 // so they can be filtered by seccomp-bpf. This filter cannot be applied
234 // on x86_32 as the arguments are passed in memory.
235 #if defined(__x86_64__) || defined(__arm__)
236 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
237 socketpair_af_inet_disallowed
,
238 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
239 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
241 socketpair(AF_INET
, SOCK_STREAM
, 0, fds
);
245 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
247 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
248 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
249 #if defined(__i386__)
250 uintptr_t args
[] = {0, 0, 0};
251 syscall(__NR_socketcall
, SYS_ACCEPT
, args
);
253 syscall(__NR_accept
, 0, 0, 0);
257 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
259 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
260 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
261 #if defined(__i386__)
262 uintptr_t args
[] = {0, 0, 0};
263 syscall(__NR_socketcall
, SYS_BIND
, args
);
265 syscall(__NR_bind
, 0, 0, 0);
269 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
271 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
272 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
273 #if defined(__i386__)
274 uintptr_t args
[] = {0, 0, 0};
275 syscall(__NR_socketcall
, SYS_CONNECT
, args
);
277 syscall(__NR_connect
, 0, 0, 0);
281 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
283 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
284 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
285 #if defined(__i386__)
286 uintptr_t args
[] = {0, 0, 0};
287 syscall(__NR_socketcall
, SYS_GETPEERNAME
, args
);
289 syscall(__NR_getpeername
, 0, 0, 0);
293 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
295 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
296 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
297 #if defined(__i386__)
298 uintptr_t args
[] = {0, 0, 0};
299 syscall(__NR_socketcall
, SYS_GETSOCKNAME
, args
);
301 syscall(__NR_getsockname
, 0, 0, 0);
305 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
307 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
308 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
309 #if defined(__i386__)
310 uintptr_t args
[] = {0, 0, 0, 0, 0};
311 syscall(__NR_socketcall
, SYS_GETSOCKOPT
, args
);
313 syscall(__NR_getsockname
, 0, 0, 0, 0, 0);
317 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
319 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
320 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
321 #if defined(__i386__)
322 uintptr_t args
[] = {0, 0};
323 syscall(__NR_socketcall
, SYS_LISTEN
, args
);
325 syscall(__NR_listen
, 0, 0);
329 // On x86_64 architecture, there is no __NR_recv system call. Note: recv()
330 // syscall wrapper usually uses __NR_recvfrom, instead, (like in glibc).
331 #if defined(__i386__) || defined(__arm__)
332 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
334 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
335 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
336 #if defined(__i386__)
337 uintptr_t args
[] = {0, 0, 0, 0};
338 syscall(__NR_socketcall
, SYS_RECV
, args
);
340 syscall(__NR_recv
, 0, 0, 0, 0);
345 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
347 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
348 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
349 #if defined(__i386__)
350 uintptr_t args
[] = {0, 0, 0, 0, 0, 0};
351 syscall(__NR_socketcall
, SYS_RECVFROM
, args
);
353 syscall(__NR_recvfrom
, 0, 0, 0, 0, 0, 0);
357 // On x86_64 architecture, there is no __NR_send system call. Note: send()
358 // syscall wrapper usually uses __NR_sendto, instead, (like in glibc).
359 #if defined(__i386__) || defined(__arm__)
360 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
362 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
363 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
364 #if defined(__i386__)
365 uintptr_t args
[] = {0, 0, 0, 0};
366 syscall(__NR_socketcall
, SYS_SEND
, args
);
368 syscall(__NR_send
, 0, 0, 0, 0);
373 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
375 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
376 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
377 #if defined(__i386__)
378 uintptr_t args
[] = {0, 0, 0, 0, 0, 0};
379 syscall(__NR_socketcall
, SYS_SENDTO
, args
);
381 syscall(__NR_sendto
, 0, 0, 0, 0, 0, 0);
385 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
387 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
388 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
389 #if defined(__i386__)
390 uintptr_t args
[] = {0, 0, 0, 0, 0};
391 syscall(__NR_socketcall
, SYS_SETSOCKOPT
, args
);
393 syscall(__NR_setsockopt
, 0, 0, 0, 0, 0);
397 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
399 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
400 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
401 #if defined(__i386__)
402 uintptr_t args
[] = {0, 0, 0};
403 syscall(__NR_socketcall
, SYS_SOCKET
, args
);
405 syscall(__NR_socket
, 0, 0, 0);
409 BPF_TEST_C(NaClNonSfiSandboxTest
,
411 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
412 base::ScopedFD fds
[2];
414 BPF_ASSERT_EQ(0, fcntl(fds
[0].get(), F_SETFD
, FD_CLOEXEC
));
417 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
419 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
420 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
421 base::ScopedFD fds
[2];
423 fcntl(fds
[0].get(), F_SETFD
, 99);
426 BPF_TEST_C(NaClNonSfiSandboxTest
,
427 fcntl_GETFL_SETFL_allowed
,
428 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
429 base::ScopedFD fds
[2];
431 const int fd
= fds
[0].get();
432 BPF_ASSERT_EQ(0, fcntl(fd
, F_GETFL
));
433 BPF_ASSERT_EQ(0, fcntl(fd
, F_SETFL
, O_RDWR
| O_NONBLOCK
));
434 BPF_ASSERT_EQ(O_NONBLOCK
, fcntl(fd
, F_GETFL
));
437 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
439 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
440 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
441 base::ScopedFD fds
[2];
443 fcntl(fds
[0].get(), F_SETFL
, O_APPEND
);
446 void DoFcntl(int fd
, int cmd
) {
447 // fcntl in PNaCl toolchain returns an error without calling actual system
448 // call for unknown |cmd|. So, instead, here we use syscall().
449 #if defined(OS_NACL_NONSFI)
450 syscall(__NR_fcntl64
, fd
, cmd
);
456 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
458 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
459 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
463 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
465 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
466 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
467 DoFcntl(0, F_DUPFD_CLOEXEC
);
470 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
471 FutexWithRequeuePriorityInheritence
,
473 sandbox::GetFutexErrorMessageContentForTests()),
474 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
475 syscall(__NR_futex
, NULL
, FUTEX_CMP_REQUEUE_PI
, 0, NULL
, NULL
, 0);
479 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
480 FutexWithRequeuePriorityInheritencePrivate
,
482 sandbox::GetFutexErrorMessageContentForTests()),
483 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
484 syscall(__NR_futex
, NULL
, FUTEX_CMP_REQUEUE_PI_PRIVATE
, 0, NULL
, NULL
, 0);
488 BPF_TEST_C(NaClNonSfiSandboxTest
,
489 StartingAndJoiningThreadWorks
,
490 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
491 base::Thread
thread("sandbox_tests");
492 BPF_ASSERT(thread
.Start());
493 // |thread|'s destructor will join the thread.
496 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
497 FutexWithUnlockPIPrivate
,
499 sandbox::GetFutexErrorMessageContentForTests()),
500 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
501 syscall(__NR_futex
, NULL
, FUTEX_UNLOCK_PI_PRIVATE
, 0, NULL
, NULL
, 0);
505 void* DoMmap(int prot
, int flags
) {
506 #if defined(OS_NACL_NONSFI)
507 // When PROT_EXEC is set, PNaCl toolchain's mmap() system call wrapper uses
508 // two system calls mmap2(2) and mprotect(2), so that we cannot test
509 // sandbox with the wrapper. Instead, here we use syscall().
510 return reinterpret_cast<void*>(
511 syscall(__NR_mmap2
, NULL
, getpagesize(), prot
, flags
, -1, 0));
513 return mmap(NULL
, getpagesize(), prot
, flags
, -1, 0);
517 void* DoAllowedAnonymousMmap() {
518 return DoMmap(PROT_READ
| PROT_WRITE
, MAP_ANONYMOUS
| MAP_SHARED
);
521 BPF_TEST_C(NaClNonSfiSandboxTest
,
523 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
524 void* ptr
= DoAllowedAnonymousMmap();
525 BPF_ASSERT_NE(MAP_FAILED
, ptr
);
526 BPF_ASSERT_EQ(0, munmap(ptr
, getpagesize()));
529 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
531 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
532 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
533 DoMmap(PROT_READ
| PROT_WRITE
, MAP_ANONYMOUS
| MAP_POPULATE
);
536 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
538 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
539 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
540 DoMmap(PROT_READ
| PROT_GROWSDOWN
, MAP_ANONYMOUS
);
543 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
545 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
546 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
547 DoMmap(PROT_EXEC
, MAP_ANONYMOUS
);
550 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
552 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
553 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
554 DoMmap(PROT_READ
| PROT_EXEC
, MAP_ANONYMOUS
);
557 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
559 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
560 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
561 DoMmap(PROT_WRITE
| PROT_EXEC
, MAP_ANONYMOUS
);
564 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
565 mmap_read_write_exec
,
566 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
567 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
568 DoMmap(PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_ANONYMOUS
);
571 BPF_TEST_C(NaClNonSfiSandboxTest
,
573 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
574 void* ptr
= DoAllowedAnonymousMmap();
575 BPF_ASSERT_NE(MAP_FAILED
, ptr
);
576 BPF_ASSERT_EQ(0, mprotect(ptr
, getpagesize(), PROT_READ
));
577 BPF_ASSERT_EQ(0, munmap(ptr
, getpagesize()));
580 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
581 mprotect_unallowed_prot
,
582 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
583 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
584 // We have tested DoAllowedAnonymousMmap is allowed in
585 // mmap_allowed, so we can make sure the following mprotect call
586 // kills the process.
587 void* ptr
= DoAllowedAnonymousMmap();
588 BPF_ASSERT_NE(MAP_FAILED
, ptr
);
589 mprotect(ptr
, getpagesize(), PROT_READ
| PROT_GROWSDOWN
);
592 BPF_TEST_C(NaClNonSfiSandboxTest
,
594 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
595 char* next_brk
= static_cast<char*>(sbrk(0)) + getpagesize();
596 // The kernel interface must return zero for brk.
597 BPF_ASSERT_EQ(0, syscall(__NR_brk
, next_brk
));
598 // The libc wrapper translates it to ENOMEM.
600 // Note: PNaCl toolchain does not provide brk() system call wrapper.
601 #if !defined(OS_NACL_NONSFI)
603 BPF_ASSERT_EQ(-1, brk(next_brk
));
604 BPF_ASSERT_EQ(ENOMEM
, errno
);
608 // clockid restrictions are mostly tested in sandbox/ with the
609 // RestrictClockID() unittests. Some basic tests are duplicated here as
612 void CheckClock(clockid_t clockid
) {
614 ts
.tv_sec
= ts
.tv_nsec
= -1;
615 BPF_ASSERT_EQ(0, clock_gettime(clockid
, &ts
));
616 BPF_ASSERT_LE(0, ts
.tv_sec
);
617 BPF_ASSERT_LE(0, ts
.tv_nsec
);
620 BPF_TEST_C(NaClNonSfiSandboxTest
,
621 clock_gettime_allowed
,
622 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
623 CheckClock(CLOCK_MONOTONIC
);
624 CheckClock(CLOCK_PROCESS_CPUTIME_ID
);
625 CheckClock(CLOCK_REALTIME
);
626 CheckClock(CLOCK_THREAD_CPUTIME_ID
);
629 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
630 clock_gettime_crash_monotonic_raw
,
631 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
632 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
634 clock_gettime(CLOCK_MONOTONIC_RAW
, &ts
);
637 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest
,
638 invalid_syscall_crash
,
639 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
640 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy
) {
641 sandbox::Syscall::InvalidCall();
644 // The following test cases check if syscalls return EPERM regardless
646 #define RESTRICT_SYSCALL_EPERM_TEST(name) \
647 BPF_TEST_C(NaClNonSfiSandboxTest, \
649 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { \
651 BPF_ASSERT_EQ(-1, syscall(__NR_##name, 0, 0, 0, 0, 0, 0)); \
652 BPF_ASSERT_EQ(EPERM, errno); \
655 RESTRICT_SYSCALL_EPERM_TEST(epoll_create
);
656 #if defined(__i386__) || defined(__arm__)
657 RESTRICT_SYSCALL_EPERM_TEST(getegid32
);
658 RESTRICT_SYSCALL_EPERM_TEST(geteuid32
);
659 RESTRICT_SYSCALL_EPERM_TEST(getgid32
);
660 RESTRICT_SYSCALL_EPERM_TEST(getuid32
);
662 RESTRICT_SYSCALL_EPERM_TEST(getegid
);
663 RESTRICT_SYSCALL_EPERM_TEST(geteuid
);
664 RESTRICT_SYSCALL_EPERM_TEST(getgid
);
665 RESTRICT_SYSCALL_EPERM_TEST(getuid
);
666 RESTRICT_SYSCALL_EPERM_TEST(madvise
);
667 RESTRICT_SYSCALL_EPERM_TEST(open
);
668 RESTRICT_SYSCALL_EPERM_TEST(openat
);
669 RESTRICT_SYSCALL_EPERM_TEST(ptrace
);
670 RESTRICT_SYSCALL_EPERM_TEST(set_robust_list
);
671 #if defined(__i386__) || defined(__x86_64__)
672 RESTRICT_SYSCALL_EPERM_TEST(time
);
677 #endif // !ADDRESS_SANITIZER && !THREAD_SANITIZER &&
678 // !MEMORY_SANITIZER && !LEAK_SANITIZER