Removed unused VideoCaptureCapability parameters.
[chromium-blink-merge.git] / content / common / sandbox_seccomp_bpf_linux.cc
bloba3a1c548d142427ea1fcbf07d9112d30be5fa42c
1 // Copyright (c) 2012 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 <asm/unistd.h>
6 #include <dlfcn.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <linux/net.h>
10 #include <signal.h>
11 #include <string.h>
12 #include <sys/ioctl.h>
13 #include <sys/mman.h>
14 #include <sys/prctl.h>
15 #include <sys/socket.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <ucontext.h>
19 #include <unistd.h>
21 #include <vector>
23 #if defined(__arm__) && !defined(MAP_STACK)
24 #define MAP_STACK 0x20000 // Daisy build environment has old headers.
25 #endif
27 #include "base/basictypes.h"
28 #include "base/bind.h"
29 #include "base/callback.h"
30 #include "base/command_line.h"
31 #include "base/logging.h"
32 #include "build/build_config.h"
33 #include "content/common/sandbox_linux.h"
34 #include "content/common/sandbox_seccomp_bpf_linux.h"
35 #include "content/public/common/content_switches.h"
36 #include "sandbox/linux/services/broker_process.h"
38 // These are the only architectures supported for now.
39 #if defined(__i386__) || defined(__x86_64__) || \
40 (defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)))
41 #define SECCOMP_BPF_SANDBOX
42 #endif
44 #if defined(SECCOMP_BPF_SANDBOX)
45 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
46 #include "sandbox/linux/services/linux_syscalls.h"
48 using playground2::arch_seccomp_data;
49 using playground2::ErrorCode;
50 using playground2::Sandbox;
51 using sandbox::BrokerProcess;
53 namespace {
55 void StartSandboxWithPolicy(Sandbox::EvaluateSyscall syscall_policy,
56 BrokerProcess* broker_process);
58 inline bool RunningOnASAN() {
59 #if defined(ADDRESS_SANITIZER)
60 return true;
61 #else
62 return false;
63 #endif
66 inline bool IsChromeOS() {
67 #if defined(OS_CHROMEOS)
68 return true;
69 #else
70 return false;
71 #endif
74 inline bool IsArchitectureX86_64() {
75 #if defined(__x86_64__)
76 return true;
77 #else
78 return false;
79 #endif
82 inline bool IsArchitectureI386() {
83 #if defined(__i386__)
84 return true;
85 #else
86 return false;
87 #endif
90 inline bool IsArchitectureArm() {
91 #if defined(__arm__)
92 return true;
93 #else
94 return false;
95 #endif
98 inline bool IsUsingToolKitGtk() {
99 #if defined(TOOLKIT_GTK)
100 return true;
101 #else
102 return false;
103 #endif
106 // Write |error_message| to stderr. Similar to RawLog(), but a bit more careful
107 // about async-signal safety. |size| is the size to write and should typically
108 // not include a terminating \0.
109 void WriteToStdErr(const char* error_message, size_t size) {
110 while (size > 0) {
111 // TODO(jln): query the current policy to check if send() is available and
112 // use it to perform a non blocking write.
113 const int ret = HANDLE_EINTR(write(STDERR_FILENO, error_message, size));
114 // We can't handle any type of error here.
115 if (ret <= 0 || static_cast<size_t>(ret) > size) break;
116 size -= ret;
117 error_message += ret;
121 // Print a seccomp-bpf failure to handle |sysno| to stderr in an
122 // async-signal safe way.
123 void PrintSyscallError(uint32_t sysno) {
124 if (sysno >= 1024)
125 sysno = 0;
126 // TODO(markus): replace with async-signal safe snprintf when available.
127 const size_t kNumDigits = 4;
128 char sysno_base10[kNumDigits];
129 uint32_t rem = sysno;
130 uint32_t mod = 0;
131 for (int i = kNumDigits - 1; i >= 0; i--) {
132 mod = rem % 10;
133 rem /= 10;
134 sysno_base10[i] = '0' + mod;
136 static const char kSeccompErrorPrefix[] =
137 __FILE__":**CRASHING**:seccomp-bpf failure in syscall ";
138 static const char kSeccompErrorPostfix[] = "\n";
139 WriteToStdErr(kSeccompErrorPrefix, sizeof(kSeccompErrorPrefix) - 1);
140 WriteToStdErr(sysno_base10, sizeof(sysno_base10));
141 WriteToStdErr(kSeccompErrorPostfix, sizeof(kSeccompErrorPostfix) - 1);
144 intptr_t CrashSIGSYS_Handler(const struct arch_seccomp_data& args, void* aux) {
145 uint32_t syscall = args.nr;
146 if (syscall >= 1024)
147 syscall = 0;
148 PrintSyscallError(syscall);
150 // Encode 8-bits of the 1st two arguments too, so we can discern which socket
151 // type, which fcntl, ... etc., without being likely to hit a mapped
152 // address.
153 // Do not encode more bits here without thinking about increasing the
154 // likelihood of collision with mapped pages.
155 syscall |= ((args.args[0] & 0xffUL) << 12);
156 syscall |= ((args.args[1] & 0xffUL) << 20);
157 // Purposefully dereference the syscall as an address so it'll show up very
158 // clearly and easily in crash dumps.
159 volatile char* addr = reinterpret_cast<volatile char*>(syscall);
160 *addr = '\0';
161 // In case we hit a mapped address, hit the null page with just the syscall,
162 // for paranoia.
163 syscall &= 0xfffUL;
164 addr = reinterpret_cast<volatile char*>(syscall);
165 *addr = '\0';
166 for (;;)
167 _exit(1);
170 // TODO(jln): rewrite reporting functions.
171 intptr_t SIGSYSCloneFailure(const struct arch_seccomp_data& args, void* aux) {
172 // "flags" in the first argument in the kernel's clone().
173 // Mark as volatile to be able to find the value on the stack in a minidump.
174 #if !defined(NDEBUG)
175 RAW_LOG(ERROR, __FILE__":**CRASHING**:clone() failure\n");
176 #endif
177 volatile uint64_t clone_flags = args.args[0];
178 volatile char* addr;
179 if (IsArchitectureX86_64()) {
180 addr = reinterpret_cast<volatile char*>(clone_flags & 0xFFFFFF);
181 *addr = '\0';
183 // Hit the NULL page if this fails to fault.
184 addr = reinterpret_cast<volatile char*>(clone_flags & 0xFFF);
185 *addr = '\0';
186 for (;;)
187 _exit(1);
190 // TODO(jln): rewrite reporting functions.
191 intptr_t SIGSYSPrctlFailure(const struct arch_seccomp_data& args,
192 void* /* aux */) {
193 // Mark as volatile to be able to find the value on the stack in a minidump.
194 #if !defined(NDEBUG)
195 RAW_LOG(ERROR, __FILE__":**CRASHING**:prctl() failure\n");
196 #endif
197 volatile uint64_t option = args.args[0];
198 volatile char* addr =
199 reinterpret_cast<volatile char*>(option & 0xFFF);
200 *addr = '\0';
201 for (;;)
202 _exit(1);
205 intptr_t SIGSYSIoctlFailure(const struct arch_seccomp_data& args,
206 void* /* aux */) {
207 // Make "request" volatile so that we can see it on the stack in a minidump.
208 #if !defined(NDEBUG)
209 RAW_LOG(ERROR, __FILE__":**CRASHING**:ioctl() failure\n");
210 #endif
211 volatile uint64_t request = args.args[1];
212 volatile char* addr = reinterpret_cast<volatile char*>(request & 0xFFFF);
213 *addr = '\0';
214 // Hit the NULL page if this fails.
215 addr = reinterpret_cast<volatile char*>(request & 0xFFF);
216 *addr = '\0';
217 for (;;)
218 _exit(1);
221 bool IsAcceleratedVideoDecodeEnabled() {
222 // Accelerated video decode is currently enabled on Chrome OS,
223 // but not on Linux: crbug.com/137247.
224 bool is_enabled = IsChromeOS();
226 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
227 is_enabled = is_enabled &&
228 !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode);
230 return is_enabled;
233 intptr_t GpuSIGSYS_Handler(const struct arch_seccomp_data& args,
234 void* aux_broker_process) {
235 RAW_CHECK(aux_broker_process);
236 BrokerProcess* broker_process =
237 static_cast<BrokerProcess*>(aux_broker_process);
238 switch (args.nr) {
239 case __NR_access:
240 return broker_process->Access(reinterpret_cast<const char*>(args.args[0]),
241 static_cast<int>(args.args[1]));
242 case __NR_open:
243 return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
244 static_cast<int>(args.args[1]));
245 case __NR_openat:
246 // Allow using openat() as open().
247 if (static_cast<int>(args.args[0]) == AT_FDCWD) {
248 return
249 broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
250 static_cast<int>(args.args[2]));
251 } else {
252 return -EPERM;
254 default:
255 RAW_CHECK(false);
256 return -ENOSYS;
260 // The functions below cover all existing i386, x86_64, and ARM system calls;
261 // excluding syscalls made obsolete in ARM EABI.
262 // The implicitly defined sets form a partition of the sets of
263 // system calls.
265 // TODO(jln) we need to restrict the first parameter!
266 bool IsKill(int sysno) {
267 switch (sysno) {
268 case __NR_kill:
269 case __NR_tkill:
270 case __NR_tgkill:
271 return true;
272 default:
273 return false;
277 bool IsAllowedGettime(int sysno) {
278 switch (sysno) {
279 case __NR_clock_gettime:
280 case __NR_gettimeofday:
281 #if defined(__i386__) || defined(__x86_64__)
282 case __NR_time:
283 #endif
284 return true;
285 case __NR_adjtimex: // Privileged.
286 case __NR_clock_adjtime: // Privileged.
287 case __NR_clock_getres: // Could be allowed.
288 case __NR_clock_nanosleep: // Could be allowed.
289 case __NR_clock_settime: // Privileged.
290 #if defined(__i386__)
291 case __NR_ftime: // Obsolete.
292 #endif
293 case __NR_settimeofday: // Privileged.
294 #if defined(__i386__)
295 case __NR_stime:
296 #endif
297 default:
298 return false;
302 bool IsCurrentDirectory(int sysno) {
303 switch (sysno) {
304 case __NR_getcwd:
305 case __NR_chdir:
306 case __NR_fchdir:
307 return true;
308 default:
309 return false;
313 bool IsUmask(int sysno) {
314 switch (sysno) {
315 case __NR_umask:
316 return true;
317 default:
318 return false;
322 // System calls that directly access the file system. They might acquire
323 // a new file descriptor or otherwise perform an operation directly
324 // via a path.
325 // Both EPERM and ENOENT are valid errno unless otherwise noted in comment.
326 bool IsFileSystem(int sysno) {
327 switch (sysno) {
328 case __NR_access: // EPERM not a valid errno.
329 case __NR_chmod:
330 case __NR_chown:
331 #if defined(__i386__) || defined(__arm__)
332 case __NR_chown32:
333 #endif
334 case __NR_creat:
335 case __NR_execve:
336 case __NR_faccessat: // EPERM not a valid errno.
337 case __NR_fchmodat:
338 case __NR_fchownat: // Should be called chownat ?
339 #if defined(__x86_64__)
340 case __NR_newfstatat: // fstatat(). EPERM not a valid errno.
341 #elif defined(__i386__) || defined(__arm__)
342 case __NR_fstatat64:
343 #endif
344 case __NR_futimesat: // Should be called utimesat ?
345 case __NR_lchown:
346 #if defined(__i386__) || defined(__arm__)
347 case __NR_lchown32:
348 #endif
349 case __NR_link:
350 case __NR_linkat:
351 case __NR_lookup_dcookie: // ENOENT not a valid errno.
352 case __NR_lstat: // EPERM not a valid errno.
353 #if defined(__i386__)
354 case __NR_oldlstat:
355 #endif
356 #if defined(__i386__) || defined(__arm__)
357 case __NR_lstat64:
358 #endif
359 case __NR_mkdir:
360 case __NR_mkdirat:
361 case __NR_mknod:
362 case __NR_mknodat:
363 case __NR_open:
364 case __NR_openat:
365 case __NR_readlink: // EPERM not a valid errno.
366 case __NR_readlinkat:
367 case __NR_rename:
368 case __NR_renameat:
369 case __NR_rmdir:
370 case __NR_stat: // EPERM not a valid errno.
371 #if defined(__i386__)
372 case __NR_oldstat:
373 #endif
374 #if defined(__i386__) || defined(__arm__)
375 case __NR_stat64:
376 #endif
377 case __NR_statfs: // EPERM not a valid errno.
378 #if defined(__i386__) || defined(__arm__)
379 case __NR_statfs64:
380 #endif
381 case __NR_symlink:
382 case __NR_symlinkat:
383 case __NR_truncate:
384 #if defined(__i386__) || defined(__arm__)
385 case __NR_truncate64:
386 #endif
387 case __NR_unlink:
388 case __NR_unlinkat:
389 case __NR_uselib: // Neither EPERM, nor ENOENT are valid errno.
390 case __NR_ustat: // Same as above. Deprecated.
391 #if defined(__i386__) || defined(__x86_64__)
392 case __NR_utime:
393 #endif
394 case __NR_utimensat: // New.
395 case __NR_utimes:
396 return true;
397 default:
398 return false;
402 bool IsAllowedFileSystemAccessViaFd(int sysno) {
403 switch (sysno) {
404 case __NR_fstat:
405 #if defined(__i386__) || defined(__arm__)
406 case __NR_fstat64:
407 #endif
408 return true;
409 // TODO(jln): these should be denied gracefully as well (moved below).
410 #if defined(__i386__) || defined(__x86_64__)
411 case __NR_fadvise64: // EPERM not a valid errno.
412 #endif
413 #if defined(__i386__)
414 case __NR_fadvise64_64:
415 #endif
416 #if defined(__arm__)
417 case __NR_arm_fadvise64_64:
418 #endif
419 case __NR_fdatasync: // EPERM not a valid errno.
420 case __NR_flock: // EPERM not a valid errno.
421 case __NR_fstatfs: // Give information about the whole filesystem.
422 #if defined(__i386__) || defined(__arm__)
423 case __NR_fstatfs64:
424 #endif
425 case __NR_fsync: // EPERM not a valid errno.
426 #if defined(__i386__)
427 case __NR_oldfstat:
428 #endif
429 #if defined(__i386__) || defined(__x86_64__)
430 case __NR_sync_file_range: // EPERM not a valid errno.
431 #elif defined(__arm__)
432 case __NR_arm_sync_file_range: // EPERM not a valid errno.
433 #endif
434 default:
435 return false;
439 // EPERM is a good errno for any of these.
440 bool IsDeniedFileSystemAccessViaFd(int sysno) {
441 switch (sysno) {
442 case __NR_fallocate:
443 case __NR_fchmod:
444 case __NR_fchown:
445 case __NR_ftruncate:
446 #if defined(__i386__) || defined(__arm__)
447 case __NR_fchown32:
448 case __NR_ftruncate64:
449 #endif
450 case __NR_getdents: // EPERM not a valid errno.
451 case __NR_getdents64: // EPERM not a valid errno.
452 #if defined(__i386__)
453 case __NR_readdir:
454 #endif
455 return true;
456 default:
457 return false;
461 bool IsGetSimpleId(int sysno) {
462 switch (sysno) {
463 case __NR_capget:
464 case __NR_getegid:
465 case __NR_geteuid:
466 case __NR_getgid:
467 case __NR_getgroups:
468 case __NR_getpid:
469 case __NR_getppid:
470 case __NR_getresgid:
471 case __NR_getsid:
472 case __NR_gettid:
473 case __NR_getuid:
474 case __NR_getresuid:
475 #if defined(__i386__) || defined(__arm__)
476 case __NR_getegid32:
477 case __NR_geteuid32:
478 case __NR_getgid32:
479 case __NR_getgroups32:
480 case __NR_getresgid32:
481 case __NR_getresuid32:
482 case __NR_getuid32:
483 #endif
484 return true;
485 default:
486 return false;
490 bool IsProcessPrivilegeChange(int sysno) {
491 switch (sysno) {
492 case __NR_capset:
493 #if defined(__i386__) || defined(__x86_64__)
494 case __NR_ioperm: // Intel privilege.
495 case __NR_iopl: // Intel privilege.
496 #endif
497 case __NR_setfsgid:
498 case __NR_setfsuid:
499 case __NR_setgid:
500 case __NR_setgroups:
501 case __NR_setregid:
502 case __NR_setresgid:
503 case __NR_setresuid:
504 case __NR_setreuid:
505 case __NR_setuid:
506 #if defined(__i386__) || defined(__arm__)
507 case __NR_setfsgid32:
508 case __NR_setfsuid32:
509 case __NR_setgid32:
510 case __NR_setgroups32:
511 case __NR_setregid32:
512 case __NR_setresgid32:
513 case __NR_setresuid32:
514 case __NR_setreuid32:
515 case __NR_setuid32:
516 #endif
517 return true;
518 default:
519 return false;
523 bool IsProcessGroupOrSession(int sysno) {
524 switch (sysno) {
525 case __NR_setpgid:
526 case __NR_getpgrp:
527 case __NR_setsid:
528 case __NR_getpgid:
529 return true;
530 default:
531 return false;
535 bool IsAllowedSignalHandling(int sysno) {
536 switch (sysno) {
537 case __NR_rt_sigaction:
538 case __NR_rt_sigprocmask:
539 case __NR_rt_sigreturn:
540 #if defined(__i386__) || defined(__arm__)
541 case __NR_sigaction:
542 case __NR_sigprocmask:
543 case __NR_sigreturn:
544 #endif
545 return true;
546 case __NR_rt_sigpending:
547 case __NR_rt_sigqueueinfo:
548 case __NR_rt_sigsuspend:
549 case __NR_rt_sigtimedwait:
550 case __NR_rt_tgsigqueueinfo:
551 case __NR_sigaltstack:
552 case __NR_signalfd:
553 case __NR_signalfd4:
554 #if defined(__i386__) || defined(__arm__)
555 case __NR_sigpending:
556 case __NR_sigsuspend:
557 #endif
558 #if defined(__i386__)
559 case __NR_signal:
560 case __NR_sgetmask: // Obsolete.
561 case __NR_ssetmask:
562 #endif
563 default:
564 return false;
568 bool IsAllowedOperationOnFd(int sysno) {
569 switch (sysno) {
570 case __NR_close:
571 case __NR_dup:
572 case __NR_dup2:
573 case __NR_dup3:
574 #if defined(__x86_64__) || defined(__arm__)
575 case __NR_shutdown:
576 #endif
577 return true;
578 case __NR_fcntl:
579 #if defined(__i386__) || defined(__arm__)
580 case __NR_fcntl64:
581 #endif
582 default:
583 return false;
587 bool IsKernelInternalApi(int sysno) {
588 switch (sysno) {
589 case __NR_restart_syscall:
590 #if defined(__arm__)
591 case __ARM_NR_cmpxchg:
592 #endif
593 return true;
594 default:
595 return false;
599 // This should be thought through in conjunction with IsFutex().
600 bool IsAllowedProcessStartOrDeath(int sysno) {
601 switch (sysno) {
602 case __NR_clone: // TODO(jln): restrict flags.
603 case __NR_exit:
604 case __NR_exit_group:
605 case __NR_wait4:
606 case __NR_waitid:
607 #if defined(__i386__)
608 case __NR_waitpid:
609 #endif
610 return true;
611 case __NR_setns: // Privileged.
612 case __NR_fork:
613 #if defined(__i386__) || defined(__x86_64__)
614 case __NR_get_thread_area:
615 case __NR_set_thread_area:
616 #endif
617 case __NR_set_tid_address:
618 case __NR_unshare:
619 case __NR_vfork:
620 default:
621 return false;
625 // It's difficult to restrict those, but there is attack surface here.
626 bool IsFutex(int sysno) {
627 switch (sysno) {
628 case __NR_futex:
629 case __NR_get_robust_list:
630 case __NR_set_robust_list:
631 return true;
632 default:
633 return false;
637 bool IsAllowedEpoll(int sysno) {
638 switch (sysno) {
639 case __NR_epoll_create:
640 case __NR_epoll_create1:
641 case __NR_epoll_ctl:
642 case __NR_epoll_wait:
643 return true;
644 default:
645 #if defined(__x86_64__)
646 case __NR_epoll_ctl_old:
647 #endif
648 case __NR_epoll_pwait:
649 #if defined(__x86_64__)
650 case __NR_epoll_wait_old:
651 #endif
652 return false;
656 bool IsAllowedGetOrModifySocket(int sysno) {
657 switch (sysno) {
658 case __NR_pipe:
659 case __NR_pipe2:
660 return true;
661 default:
662 #if defined(__x86_64__) || defined(__arm__)
663 case __NR_socketpair: // We will want to inspect its argument.
664 #endif
665 return false;
669 bool IsDeniedGetOrModifySocket(int sysno) {
670 switch (sysno) {
671 #if defined(__x86_64__) || defined(__arm__)
672 case __NR_accept:
673 case __NR_accept4:
674 case __NR_bind:
675 case __NR_connect:
676 case __NR_socket:
677 case __NR_listen:
678 return true;
679 #endif
680 default:
681 return false;
685 #if defined(__i386__)
686 // Big multiplexing system call for sockets.
687 bool IsSocketCall(int sysno) {
688 switch (sysno) {
689 case __NR_socketcall:
690 return true;
691 default:
692 return false;
695 #endif
697 #if defined(__x86_64__) || defined(__arm__)
698 bool IsNetworkSocketInformation(int sysno) {
699 switch (sysno) {
700 case __NR_getpeername:
701 case __NR_getsockname:
702 case __NR_getsockopt:
703 case __NR_setsockopt:
704 return true;
705 default:
706 return false;
709 #endif
711 bool IsAllowedAddressSpaceAccess(int sysno) {
712 switch (sysno) {
713 case __NR_brk:
714 case __NR_mlock:
715 case __NR_munlock:
716 case __NR_munmap:
717 return true;
718 case __NR_madvise:
719 case __NR_mincore:
720 case __NR_mlockall:
721 #if defined(__i386__) || defined(__x86_64__)
722 case __NR_mmap:
723 #endif
724 #if defined(__i386__) || defined(__arm__)
725 case __NR_mmap2:
726 #endif
727 #if defined(__i386__) || defined(__x86_64__)
728 case __NR_modify_ldt:
729 #endif
730 case __NR_mprotect:
731 case __NR_mremap:
732 case __NR_msync:
733 case __NR_munlockall:
734 case __NR_readahead:
735 case __NR_remap_file_pages:
736 #if defined(__i386__)
737 case __NR_vm86:
738 case __NR_vm86old:
739 #endif
740 default:
741 return false;
745 bool IsAllowedGeneralIo(int sysno) {
746 switch (sysno) {
747 case __NR_lseek:
748 #if defined(__i386__) || defined(__arm__)
749 case __NR__llseek:
750 #endif
751 case __NR_poll:
752 case __NR_ppoll:
753 case __NR_pselect6:
754 case __NR_read:
755 case __NR_readv:
756 #if defined(__arm__)
757 case __NR_recv:
758 #endif
759 #if defined(__x86_64__) || defined(__arm__)
760 case __NR_recvfrom: // Could specify source.
761 case __NR_recvmsg: // Could specify source.
762 #endif
763 #if defined(__i386__) || defined(__x86_64__)
764 case __NR_select:
765 #endif
766 #if defined(__i386__) || defined(__arm__)
767 case __NR__newselect:
768 #endif
769 #if defined(__arm__)
770 case __NR_send:
771 #endif
772 #if defined(__x86_64__) || defined(__arm__)
773 case __NR_sendmsg: // Could specify destination.
774 case __NR_sendto: // Could specify destination.
775 #endif
776 case __NR_write:
777 case __NR_writev:
778 return true;
779 case __NR_ioctl: // Can be very powerful.
780 case __NR_pread64:
781 case __NR_preadv:
782 case __NR_pwrite64:
783 case __NR_pwritev:
784 case __NR_recvmmsg: // Could specify source.
785 case __NR_sendfile:
786 #if defined(__i386__) || defined(__arm__)
787 case __NR_sendfile64:
788 #endif
789 case __NR_sendmmsg: // Could specify destination.
790 case __NR_splice:
791 case __NR_tee:
792 case __NR_vmsplice:
793 default:
794 return false;
798 bool IsAllowedPrctl(int sysno) {
799 switch (sysno) {
800 case __NR_prctl:
801 return true;
802 default:
803 #if defined(__x86_64__)
804 case __NR_arch_prctl:
805 #endif
806 return false;
810 bool IsAllowedBasicScheduler(int sysno) {
811 switch (sysno) {
812 case __NR_sched_yield:
813 case __NR_pause:
814 case __NR_nanosleep:
815 return true;
816 case __NR_getpriority:
817 #if defined(__i386__) || defined(__arm__)
818 case __NR_nice:
819 #endif
820 case __NR_setpriority:
821 default:
822 return false;
826 bool IsAdminOperation(int sysno) {
827 switch (sysno) {
828 #if defined(__i386__) || defined(__arm__)
829 case __NR_bdflush:
830 #endif
831 case __NR_kexec_load:
832 case __NR_reboot:
833 case __NR_setdomainname:
834 case __NR_sethostname:
835 case __NR_syslog:
836 return true;
837 default:
838 return false;
842 bool IsKernelModule(int sysno) {
843 switch (sysno) {
844 #if defined(__i386__) || defined(__x86_64__)
845 case __NR_create_module:
846 case __NR_get_kernel_syms: // Should ENOSYS.
847 case __NR_query_module:
848 #endif
849 case __NR_delete_module:
850 case __NR_init_module:
851 return true;
852 default:
853 return false;
857 bool IsGlobalFSViewChange(int sysno) {
858 switch (sysno) {
859 case __NR_pivot_root:
860 case __NR_chroot:
861 case __NR_sync:
862 return true;
863 default:
864 return false;
868 bool IsFsControl(int sysno) {
869 switch (sysno) {
870 case __NR_mount:
871 case __NR_nfsservctl:
872 case __NR_quotactl:
873 case __NR_swapoff:
874 case __NR_swapon:
875 #if defined(__i386__)
876 case __NR_umount:
877 #endif
878 case __NR_umount2:
879 return true;
880 default:
881 return false;
885 bool IsNuma(int sysno) {
886 switch (sysno) {
887 case __NR_get_mempolicy:
888 case __NR_getcpu:
889 case __NR_mbind:
890 #if defined(__i386__) || defined(__x86_64__)
891 case __NR_migrate_pages:
892 #endif
893 case __NR_move_pages:
894 case __NR_set_mempolicy:
895 return true;
896 default:
897 return false;
901 bool IsMessageQueue(int sysno) {
902 switch (sysno) {
903 case __NR_mq_getsetattr:
904 case __NR_mq_notify:
905 case __NR_mq_open:
906 case __NR_mq_timedreceive:
907 case __NR_mq_timedsend:
908 case __NR_mq_unlink:
909 return true;
910 default:
911 return false;
915 bool IsGlobalProcessEnvironment(int sysno) {
916 switch (sysno) {
917 case __NR_acct: // Privileged.
918 #if defined(__i386__) || defined(__x86_64__)
919 case __NR_getrlimit:
920 #endif
921 #if defined(__i386__) || defined(__arm__)
922 case __NR_ugetrlimit:
923 #endif
924 #if defined(__i386__)
925 case __NR_ulimit:
926 #endif
927 case __NR_getrusage:
928 case __NR_personality: // Can change its personality as well.
929 case __NR_prlimit64: // Like setrlimit / getrlimit.
930 case __NR_setrlimit:
931 case __NR_times:
932 return true;
933 default:
934 return false;
938 bool IsDebug(int sysno) {
939 switch (sysno) {
940 case __NR_ptrace:
941 case __NR_process_vm_readv:
942 case __NR_process_vm_writev:
943 #if defined(__i386__) || defined(__x86_64__)
944 case __NR_kcmp:
945 #endif
946 return true;
947 default:
948 return false;
952 bool IsGlobalSystemStatus(int sysno) {
953 switch (sysno) {
954 case __NR__sysctl:
955 case __NR_sysfs:
956 case __NR_sysinfo:
957 case __NR_uname:
958 #if defined(__i386__)
959 case __NR_olduname:
960 case __NR_oldolduname:
961 #endif
962 return true;
963 default:
964 return false;
968 bool IsEventFd(int sysno) {
969 switch (sysno) {
970 case __NR_eventfd:
971 case __NR_eventfd2:
972 return true;
973 default:
974 return false;
978 // Asynchronous I/O API.
979 bool IsAsyncIo(int sysno) {
980 switch (sysno) {
981 case __NR_io_cancel:
982 case __NR_io_destroy:
983 case __NR_io_getevents:
984 case __NR_io_setup:
985 case __NR_io_submit:
986 return true;
987 default:
988 return false;
992 bool IsKeyManagement(int sysno) {
993 switch (sysno) {
994 case __NR_add_key:
995 case __NR_keyctl:
996 case __NR_request_key:
997 return true;
998 default:
999 return false;
1003 #if defined(__x86_64__) || defined(__arm__)
1004 bool IsSystemVSemaphores(int sysno) {
1005 switch (sysno) {
1006 case __NR_semctl:
1007 case __NR_semget:
1008 case __NR_semop:
1009 case __NR_semtimedop:
1010 return true;
1011 default:
1012 return false;
1015 #endif
1017 #if defined(__x86_64__) || defined(__arm__)
1018 // These give a lot of ambient authority and bypass the setuid sandbox.
1019 bool IsSystemVSharedMemory(int sysno) {
1020 switch (sysno) {
1021 case __NR_shmat:
1022 case __NR_shmctl:
1023 case __NR_shmdt:
1024 case __NR_shmget:
1025 return true;
1026 default:
1027 return false;
1030 #endif
1032 #if defined(__x86_64__) || defined(__arm__)
1033 bool IsSystemVMessageQueue(int sysno) {
1034 switch (sysno) {
1035 case __NR_msgctl:
1036 case __NR_msgget:
1037 case __NR_msgrcv:
1038 case __NR_msgsnd:
1039 return true;
1040 default:
1041 return false;
1044 #endif
1046 #if defined(__i386__)
1047 // Big system V multiplexing system call.
1048 bool IsSystemVIpc(int sysno) {
1049 switch (sysno) {
1050 case __NR_ipc:
1051 return true;
1052 default:
1053 return false;
1056 #endif
1058 bool IsAnySystemV(int sysno) {
1059 #if defined(__x86_64__) || defined(__arm__)
1060 return IsSystemVMessageQueue(sysno) ||
1061 IsSystemVSemaphores(sysno) ||
1062 IsSystemVSharedMemory(sysno);
1063 #elif defined(__i386__)
1064 return IsSystemVIpc(sysno);
1065 #endif
1068 bool IsAdvancedScheduler(int sysno) {
1069 switch (sysno) {
1070 case __NR_ioprio_get: // IO scheduler.
1071 case __NR_ioprio_set:
1072 case __NR_sched_get_priority_max:
1073 case __NR_sched_get_priority_min:
1074 case __NR_sched_getaffinity:
1075 case __NR_sched_getparam:
1076 case __NR_sched_getscheduler:
1077 case __NR_sched_rr_get_interval:
1078 case __NR_sched_setaffinity:
1079 case __NR_sched_setparam:
1080 case __NR_sched_setscheduler:
1081 return true;
1082 default:
1083 return false;
1087 bool IsInotify(int sysno) {
1088 switch (sysno) {
1089 case __NR_inotify_add_watch:
1090 case __NR_inotify_init:
1091 case __NR_inotify_init1:
1092 case __NR_inotify_rm_watch:
1093 return true;
1094 default:
1095 return false;
1099 bool IsFaNotify(int sysno) {
1100 switch (sysno) {
1101 case __NR_fanotify_init:
1102 case __NR_fanotify_mark:
1103 return true;
1104 default:
1105 return false;
1109 bool IsTimer(int sysno) {
1110 switch (sysno) {
1111 case __NR_getitimer:
1112 #if defined(__i386__) || defined(__x86_64__)
1113 case __NR_alarm:
1114 #endif
1115 case __NR_setitimer:
1116 return true;
1117 default:
1118 return false;
1122 bool IsAdvancedTimer(int sysno) {
1123 switch (sysno) {
1124 case __NR_timer_create:
1125 case __NR_timer_delete:
1126 case __NR_timer_getoverrun:
1127 case __NR_timer_gettime:
1128 case __NR_timer_settime:
1129 case __NR_timerfd_create:
1130 case __NR_timerfd_gettime:
1131 case __NR_timerfd_settime:
1132 return true;
1133 default:
1134 return false;
1138 bool IsExtendedAttributes(int sysno) {
1139 switch (sysno) {
1140 case __NR_fgetxattr:
1141 case __NR_flistxattr:
1142 case __NR_fremovexattr:
1143 case __NR_fsetxattr:
1144 case __NR_getxattr:
1145 case __NR_lgetxattr:
1146 case __NR_listxattr:
1147 case __NR_llistxattr:
1148 case __NR_lremovexattr:
1149 case __NR_lsetxattr:
1150 case __NR_removexattr:
1151 case __NR_setxattr:
1152 return true;
1153 default:
1154 return false;
1158 // Various system calls that need to be researched.
1159 // TODO(jln): classify this better.
1160 bool IsMisc(int sysno) {
1161 switch (sysno) {
1162 case __NR_name_to_handle_at:
1163 case __NR_open_by_handle_at:
1164 case __NR_perf_event_open:
1165 case __NR_syncfs:
1166 case __NR_vhangup:
1167 // The system calls below are not implemented.
1168 #if defined(__i386__) || defined(__x86_64__)
1169 case __NR_afs_syscall:
1170 #endif
1171 #if defined(__i386__)
1172 case __NR_break:
1173 #endif
1174 #if defined(__i386__) || defined(__x86_64__)
1175 case __NR_getpmsg:
1176 #endif
1177 #if defined(__i386__)
1178 case __NR_gtty:
1179 case __NR_idle:
1180 case __NR_lock:
1181 case __NR_mpx:
1182 case __NR_prof:
1183 case __NR_profil:
1184 #endif
1185 #if defined(__i386__) || defined(__x86_64__)
1186 case __NR_putpmsg:
1187 #endif
1188 #if defined(__x86_64__)
1189 case __NR_security:
1190 #endif
1191 #if defined(__i386__)
1192 case __NR_stty:
1193 #endif
1194 #if defined(__x86_64__)
1195 case __NR_tuxcall:
1196 #endif
1197 case __NR_vserver:
1198 return true;
1199 default:
1200 return false;
1204 #if defined(__arm__)
1205 bool IsArmPciConfig(int sysno) {
1206 switch (sysno) {
1207 case __NR_pciconfig_iobase:
1208 case __NR_pciconfig_read:
1209 case __NR_pciconfig_write:
1210 return true;
1211 default:
1212 return false;
1216 bool IsArmPrivate(int sysno) {
1217 switch (sysno) {
1218 case __ARM_NR_breakpoint:
1219 case __ARM_NR_cacheflush:
1220 case __ARM_NR_set_tls:
1221 case __ARM_NR_usr26:
1222 case __ARM_NR_usr32:
1223 return true;
1224 default:
1225 return false;
1228 #endif // defined(__arm__)
1230 // End of the system call sets section.
1232 bool IsBaselinePolicyAllowed(int sysno) {
1233 if (IsAllowedAddressSpaceAccess(sysno) ||
1234 IsAllowedBasicScheduler(sysno) ||
1235 IsAllowedEpoll(sysno) ||
1236 IsAllowedFileSystemAccessViaFd(sysno) ||
1237 IsAllowedGeneralIo(sysno) ||
1238 IsAllowedGetOrModifySocket(sysno) ||
1239 IsAllowedGettime(sysno) ||
1240 IsAllowedPrctl(sysno) ||
1241 IsAllowedProcessStartOrDeath(sysno) ||
1242 IsAllowedSignalHandling(sysno) ||
1243 IsFutex(sysno) ||
1244 IsGetSimpleId(sysno) ||
1245 IsKernelInternalApi(sysno) ||
1246 #if defined(__arm__)
1247 IsArmPrivate(sysno) ||
1248 #endif
1249 IsKill(sysno) ||
1250 IsAllowedOperationOnFd(sysno)) {
1251 return true;
1252 } else {
1253 return false;
1257 // System calls that will trigger the crashing SIGSYS handler.
1258 bool IsBaselinePolicyWatched(int sysno) {
1259 if (IsAdminOperation(sysno) ||
1260 IsAdvancedScheduler(sysno) ||
1261 IsAdvancedTimer(sysno) ||
1262 IsAsyncIo(sysno) ||
1263 IsDebug(sysno) ||
1264 IsEventFd(sysno) ||
1265 IsExtendedAttributes(sysno) ||
1266 IsFaNotify(sysno) ||
1267 IsFsControl(sysno) ||
1268 IsGlobalFSViewChange(sysno) ||
1269 IsGlobalProcessEnvironment(sysno) ||
1270 IsGlobalSystemStatus(sysno) ||
1271 IsInotify(sysno) ||
1272 IsKernelModule(sysno) ||
1273 IsKeyManagement(sysno) ||
1274 IsMessageQueue(sysno) ||
1275 IsMisc(sysno) ||
1276 #if defined(__x86_64__)
1277 IsNetworkSocketInformation(sysno) ||
1278 #endif
1279 IsNuma(sysno) ||
1280 IsProcessGroupOrSession(sysno) ||
1281 IsProcessPrivilegeChange(sysno) ||
1282 #if defined(__i386__)
1283 IsSocketCall(sysno) || // We'll need to handle this properly to build
1284 // a x86_32 policy.
1285 #endif
1286 #if defined(__arm__)
1287 IsArmPciConfig(sysno) ||
1288 #endif
1289 IsTimer(sysno)) {
1290 return true;
1291 } else {
1292 return false;
1296 ErrorCode RestrictMmapFlags(Sandbox* sandbox) {
1297 // The flags you see are actually the allowed ones, and the variable is a
1298 // "denied" mask because of the negation operator.
1299 // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as
1300 // MAP_POPULATE.
1301 // TODO(davidung), remove MAP_DENYWRITE with updated Tegra libraries.
1302 uint32_t denied_mask = ~(MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS |
1303 MAP_STACK | MAP_NORESERVE | MAP_FIXED |
1304 MAP_DENYWRITE);
1305 return sandbox->Cond(3, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
1306 denied_mask,
1307 sandbox->Trap(CrashSIGSYS_Handler, NULL),
1308 ErrorCode(ErrorCode::ERR_ALLOWED));
1311 ErrorCode RestrictMprotectFlags(Sandbox* sandbox) {
1312 // The flags you see are actually the allowed ones, and the variable is a
1313 // "denied" mask because of the negation operator.
1314 // Significantly, we don't permit weird undocumented flags such as
1315 // PROT_GROWSDOWN.
1316 uint32_t denied_mask = ~(PROT_READ | PROT_WRITE | PROT_EXEC);
1317 return sandbox->Cond(2, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
1318 denied_mask,
1319 sandbox->Trap(CrashSIGSYS_Handler, NULL),
1320 ErrorCode(ErrorCode::ERR_ALLOWED));
1323 ErrorCode RestrictFcntlCommands(Sandbox* sandbox) {
1324 // We allow F_GETFL, F_SETFL, F_GETFD, F_SETFD, F_DUPFD, F_DUPFD_CLOEXEC,
1325 // F_SETLK, F_SETLKW and F_GETLK.
1326 // We also restrict the flags in F_SETFL. We don't want to permit flags with
1327 // a history of trouble such as O_DIRECT. The flags you see are actually the
1328 // allowed ones, and the variable is a "denied" mask because of the negation
1329 // operator.
1330 // Glibc overrides the kernel's O_LARGEFILE value. Account for this.
1331 int kOLargeFileFlag = O_LARGEFILE;
1332 if (IsArchitectureX86_64() || IsArchitectureI386())
1333 kOLargeFileFlag = 0100000;
1335 // TODO(jln): add TP_LONG/TP_SIZET types.
1336 ErrorCode::ArgType mask_long_type;
1337 if (sizeof(long) == 8)
1338 mask_long_type = ErrorCode::TP_64BIT;
1339 else if (sizeof(long) == 4)
1340 mask_long_type = ErrorCode::TP_32BIT;
1341 else
1342 NOTREACHED();
1344 unsigned long denied_mask = ~(O_ACCMODE | O_APPEND | O_NONBLOCK | O_SYNC |
1345 kOLargeFileFlag | O_CLOEXEC | O_NOATIME);
1346 return sandbox->Cond(1, ErrorCode::TP_32BIT,
1347 ErrorCode::OP_EQUAL, F_GETFL,
1348 ErrorCode(ErrorCode::ERR_ALLOWED),
1349 sandbox->Cond(1, ErrorCode::TP_32BIT,
1350 ErrorCode::OP_EQUAL, F_SETFL,
1351 sandbox->Cond(2, mask_long_type,
1352 ErrorCode::OP_HAS_ANY_BITS, denied_mask,
1353 sandbox->Trap(CrashSIGSYS_Handler, NULL),
1354 ErrorCode(ErrorCode::ERR_ALLOWED)),
1355 sandbox->Cond(1, ErrorCode::TP_32BIT,
1356 ErrorCode::OP_EQUAL, F_GETFD,
1357 ErrorCode(ErrorCode::ERR_ALLOWED),
1358 sandbox->Cond(1, ErrorCode::TP_32BIT,
1359 ErrorCode::OP_EQUAL, F_SETFD,
1360 ErrorCode(ErrorCode::ERR_ALLOWED),
1361 sandbox->Cond(1, ErrorCode::TP_32BIT,
1362 ErrorCode::OP_EQUAL, F_DUPFD,
1363 ErrorCode(ErrorCode::ERR_ALLOWED),
1364 sandbox->Cond(1, ErrorCode::TP_32BIT,
1365 ErrorCode::OP_EQUAL, F_SETLK,
1366 ErrorCode(ErrorCode::ERR_ALLOWED),
1367 sandbox->Cond(1, ErrorCode::TP_32BIT,
1368 ErrorCode::OP_EQUAL, F_SETLKW,
1369 ErrorCode(ErrorCode::ERR_ALLOWED),
1370 sandbox->Cond(1, ErrorCode::TP_32BIT,
1371 ErrorCode::OP_EQUAL, F_GETLK,
1372 ErrorCode(ErrorCode::ERR_ALLOWED),
1373 sandbox->Cond(1, ErrorCode::TP_32BIT,
1374 ErrorCode::OP_EQUAL, F_DUPFD_CLOEXEC,
1375 ErrorCode(ErrorCode::ERR_ALLOWED),
1376 sandbox->Trap(CrashSIGSYS_Handler, NULL))))))))));
1379 #if defined(__i386__)
1380 ErrorCode RestrictSocketcallCommand(Sandbox* sandbox) {
1381 // Allow the same individual syscalls as we do on ARM or x86_64.
1382 // The main difference is that we're unable to restrict the first parameter
1383 // to socketpair(2). Whilst initially sounding bad, it's noteworthy that very
1384 // few protocols actually support socketpair(2). The scary call that we're
1385 // worried about, socket(2), remains blocked.
1386 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1387 SYS_SOCKETPAIR, ErrorCode(ErrorCode::ERR_ALLOWED),
1388 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1389 SYS_SEND, ErrorCode(ErrorCode::ERR_ALLOWED),
1390 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1391 SYS_RECV, ErrorCode(ErrorCode::ERR_ALLOWED),
1392 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1393 SYS_SENDTO, ErrorCode(ErrorCode::ERR_ALLOWED),
1394 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1395 SYS_RECVFROM, ErrorCode(ErrorCode::ERR_ALLOWED),
1396 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1397 SYS_SHUTDOWN, ErrorCode(ErrorCode::ERR_ALLOWED),
1398 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1399 SYS_SENDMSG, ErrorCode(ErrorCode::ERR_ALLOWED),
1400 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1401 SYS_RECVMSG, ErrorCode(ErrorCode::ERR_ALLOWED),
1402 ErrorCode(EPERM)))))))));
1404 #endif
1406 const int kFSDeniedErrno = EPERM;
1408 ErrorCode BaselinePolicy(Sandbox* sandbox, int sysno) {
1409 if (IsBaselinePolicyAllowed(sysno)) {
1410 return ErrorCode(ErrorCode::ERR_ALLOWED);
1413 #if defined(__x86_64__) || defined(__arm__)
1414 if (sysno == __NR_socketpair) {
1415 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen.
1416 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different);
1417 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, AF_UNIX,
1418 ErrorCode(ErrorCode::ERR_ALLOWED),
1419 sandbox->Trap(CrashSIGSYS_Handler, NULL));
1421 #endif
1423 if (sysno == __NR_madvise) {
1424 // Only allow MADV_DONTNEED (aka MADV_FREE).
1425 return sandbox->Cond(2, ErrorCode::TP_32BIT,
1426 ErrorCode::OP_EQUAL, MADV_DONTNEED,
1427 ErrorCode(ErrorCode::ERR_ALLOWED),
1428 ErrorCode(EPERM));
1431 #if defined(__i386__) || defined(__x86_64__)
1432 if (sysno == __NR_mmap)
1433 return RestrictMmapFlags(sandbox);
1434 #endif
1436 #if defined(__i386__) || defined(__arm__)
1437 if (sysno == __NR_mmap2)
1438 return RestrictMmapFlags(sandbox);
1439 #endif
1441 if (sysno == __NR_mprotect)
1442 return RestrictMprotectFlags(sandbox);
1444 if (sysno == __NR_fcntl)
1445 return RestrictFcntlCommands(sandbox);
1447 #if defined(__i386__) || defined(__arm__)
1448 if (sysno == __NR_fcntl64)
1449 return RestrictFcntlCommands(sandbox);
1450 #endif
1452 if (IsFileSystem(sysno) || IsCurrentDirectory(sysno)) {
1453 return ErrorCode(kFSDeniedErrno);
1456 if (IsAnySystemV(sysno)) {
1457 return ErrorCode(EPERM);
1460 if (IsUmask(sysno) || IsDeniedFileSystemAccessViaFd(sysno) ||
1461 IsDeniedGetOrModifySocket(sysno)) {
1462 return ErrorCode(EPERM);
1465 #if defined(__i386__)
1466 if (IsSocketCall(sysno))
1467 return RestrictSocketcallCommand(sandbox);
1468 #endif
1470 if (IsBaselinePolicyWatched(sysno)) {
1471 // Previously unseen syscalls. TODO(jln): some of these should
1472 // be denied gracefully right away.
1473 return sandbox->Trap(CrashSIGSYS_Handler, NULL);
1475 // In any other case crash the program with our SIGSYS handler.
1476 return sandbox->Trap(CrashSIGSYS_Handler, NULL);
1479 // The BaselinePolicy only takes two arguments. BaselinePolicyWithAux
1480 // allows us to conform to the BPF compiler's policy type.
1481 ErrorCode BaselinePolicyWithAux(Sandbox* sandbox, int sysno, void* aux) {
1482 CHECK(!aux);
1483 return BaselinePolicy(sandbox, sysno);
1486 // Main policy for x86_64/i386. Extended by ArmGpuProcessPolicy.
1487 ErrorCode GpuProcessPolicy(Sandbox* sandbox, int sysno,
1488 void* broker_process) {
1489 switch (sysno) {
1490 case __NR_ioctl:
1491 #if defined(__i386__) || defined(__x86_64__)
1492 // The Nvidia driver uses flags not in the baseline policy
1493 // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT)
1494 case __NR_mmap:
1495 #endif
1496 // We also hit this on the linux_chromeos bot but don't yet know what
1497 // weird flags were involved.
1498 case __NR_mprotect:
1499 case __NR_sched_getaffinity:
1500 case __NR_sched_setaffinity:
1501 case __NR_setpriority:
1502 return ErrorCode(ErrorCode::ERR_ALLOWED);
1503 case __NR_access:
1504 case __NR_open:
1505 case __NR_openat:
1506 return sandbox->Trap(GpuSIGSYS_Handler, broker_process);
1507 default:
1508 if (IsEventFd(sysno))
1509 return ErrorCode(ErrorCode::ERR_ALLOWED);
1511 // Default on the baseline policy.
1512 return BaselinePolicy(sandbox, sysno);
1516 // x86_64/i386.
1517 // A GPU broker policy is the same as a GPU policy with open and
1518 // openat allowed.
1519 ErrorCode GpuBrokerProcessPolicy(Sandbox* sandbox, int sysno, void* aux) {
1520 // "aux" would typically be NULL, when called from
1521 // "EnableGpuBrokerPolicyCallBack"
1522 switch (sysno) {
1523 case __NR_access:
1524 case __NR_open:
1525 case __NR_openat:
1526 return ErrorCode(ErrorCode::ERR_ALLOWED);
1527 default:
1528 return GpuProcessPolicy(sandbox, sysno, aux);
1532 // Generic ARM GPU process sandbox, inheriting from GpuProcessPolicy.
1533 ErrorCode ArmGpuProcessPolicy(Sandbox* sandbox, int sysno,
1534 void* broker_process) {
1535 switch (sysno) {
1536 #if defined(__arm__)
1537 // ARM GPU sandbox is started earlier so we need to allow networking
1538 // in the sandbox.
1539 case __NR_connect:
1540 case __NR_getpeername:
1541 case __NR_getsockname:
1542 case __NR_sysinfo:
1543 case __NR_uname:
1544 return ErrorCode(ErrorCode::ERR_ALLOWED);
1545 // Allow only AF_UNIX for |domain|.
1546 case __NR_socket:
1547 case __NR_socketpair:
1548 return sandbox->Cond(0, ErrorCode::TP_32BIT,
1549 ErrorCode::OP_EQUAL, AF_UNIX,
1550 ErrorCode(ErrorCode::ERR_ALLOWED),
1551 ErrorCode(EPERM));
1552 #endif // defined(__arm__)
1553 default:
1554 if (IsAdvancedScheduler(sysno))
1555 return ErrorCode(ErrorCode::ERR_ALLOWED);
1557 // Default to the generic GPU policy.
1558 return GpuProcessPolicy(sandbox, sysno, broker_process);
1562 // Same as above but with shmat allowed, inheriting from GpuProcessPolicy.
1563 ErrorCode ArmGpuProcessPolicyWithShmat(Sandbox* sandbox, int sysno,
1564 void* broker_process) {
1565 #if defined(__arm__)
1566 if (sysno == __NR_shmat)
1567 return ErrorCode(ErrorCode::ERR_ALLOWED);
1568 #endif // defined(__arm__)
1570 return ArmGpuProcessPolicy(sandbox, sysno, broker_process);
1573 // A GPU broker policy is the same as a GPU policy with open and
1574 // openat allowed.
1575 ErrorCode ArmGpuBrokerProcessPolicy(Sandbox* sandbox,
1576 int sysno, void* aux) {
1577 // "aux" would typically be NULL, when called from
1578 // "EnableGpuBrokerPolicyCallBack"
1579 switch (sysno) {
1580 case __NR_access:
1581 case __NR_open:
1582 case __NR_openat:
1583 return ErrorCode(ErrorCode::ERR_ALLOWED);
1584 default:
1585 return ArmGpuProcessPolicy(sandbox, sysno, aux);
1589 // Allow clone(2) for threads.
1590 // Reject fork(2) attempts with EPERM.
1591 // Crash if anything else is attempted.
1592 // Don't restrict on ASAN.
1593 ErrorCode RestrictCloneToThreadsAndEPERMFork(Sandbox* sandbox) {
1594 // Glibc's pthread.
1595 if (!RunningOnASAN()) {
1596 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1597 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
1598 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS |
1599 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID,
1600 ErrorCode(ErrorCode::ERR_ALLOWED),
1601 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1602 CLONE_PARENT_SETTID | SIGCHLD,
1603 ErrorCode(EPERM),
1604 // ARM
1605 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1606 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD,
1607 ErrorCode(EPERM),
1608 sandbox->Trap(SIGSYSCloneFailure, NULL))));
1609 } else {
1610 return ErrorCode(ErrorCode::ERR_ALLOWED);
1614 ErrorCode RestrictPrctl(Sandbox* sandbox) {
1615 // Allow PR_SET_NAME, PR_SET_DUMPABLE, PR_GET_DUMPABLE. Will need to add
1616 // seccomp compositing in the future.
1617 // PR_SET_PTRACER is used by breakpad but not needed anymore.
1618 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1619 PR_SET_NAME, ErrorCode(ErrorCode::ERR_ALLOWED),
1620 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1621 PR_SET_DUMPABLE, ErrorCode(ErrorCode::ERR_ALLOWED),
1622 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1623 PR_GET_DUMPABLE, ErrorCode(ErrorCode::ERR_ALLOWED),
1624 sandbox->Trap(SIGSYSPrctlFailure, NULL))));
1627 ErrorCode RestrictIoctl(Sandbox* sandbox) {
1628 // Allow TCGETS and FIONREAD, trap to SIGSYSIoctlFailure otherwise.
1629 return sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, TCGETS,
1630 ErrorCode(ErrorCode::ERR_ALLOWED),
1631 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, FIONREAD,
1632 ErrorCode(ErrorCode::ERR_ALLOWED),
1633 sandbox->Trap(SIGSYSIoctlFailure, NULL)));
1636 ErrorCode RendererOrWorkerProcessPolicy(Sandbox* sandbox, int sysno, void*) {
1637 switch (sysno) {
1638 case __NR_clone:
1639 return RestrictCloneToThreadsAndEPERMFork(sandbox);
1640 case __NR_ioctl:
1641 return RestrictIoctl(sandbox);
1642 case __NR_prctl:
1643 return RestrictPrctl(sandbox);
1644 // Allow the system calls below.
1645 case __NR_fdatasync:
1646 case __NR_fsync:
1647 case __NR_getpriority:
1648 #if defined(__i386__) || defined(__x86_64__)
1649 case __NR_getrlimit:
1650 #endif
1651 #if defined(__i386__) || defined(__arm__)
1652 case __NR_ugetrlimit:
1653 #endif
1654 case __NR_mremap: // See crbug.com/149834.
1655 case __NR_pread64:
1656 case __NR_pwrite64:
1657 case __NR_sched_getaffinity:
1658 case __NR_sched_get_priority_max:
1659 case __NR_sched_get_priority_min:
1660 case __NR_sched_getparam:
1661 case __NR_sched_getscheduler:
1662 case __NR_sched_setscheduler:
1663 case __NR_setpriority:
1664 case __NR_sysinfo:
1665 case __NR_times:
1666 case __NR_uname:
1667 return ErrorCode(ErrorCode::ERR_ALLOWED);
1668 case __NR_prlimit64:
1669 return ErrorCode(EPERM); // See crbug.com/160157.
1670 default:
1671 if (IsUsingToolKitGtk()) {
1672 #if defined(__x86_64__) || defined(__arm__)
1673 if (IsSystemVSharedMemory(sysno))
1674 return ErrorCode(ErrorCode::ERR_ALLOWED);
1675 #endif
1676 #if defined(__i386__)
1677 if (IsSystemVIpc(sysno))
1678 return ErrorCode(ErrorCode::ERR_ALLOWED);
1679 #endif
1682 // Default on the baseline policy.
1683 return BaselinePolicy(sandbox, sysno);
1687 ErrorCode FlashProcessPolicy(Sandbox* sandbox, int sysno, void*) {
1688 switch (sysno) {
1689 case __NR_clone:
1690 return RestrictCloneToThreadsAndEPERMFork(sandbox);
1691 case __NR_pread64:
1692 case __NR_pwrite64:
1693 case __NR_sched_get_priority_max:
1694 case __NR_sched_get_priority_min:
1695 case __NR_sched_getaffinity:
1696 case __NR_sched_getparam:
1697 case __NR_sched_getscheduler:
1698 case __NR_sched_setscheduler:
1699 case __NR_times:
1700 return ErrorCode(ErrorCode::ERR_ALLOWED);
1701 case __NR_ioctl:
1702 return ErrorCode(ENOTTY); // Flash Access.
1703 default:
1704 if (IsUsingToolKitGtk()) {
1705 #if defined(__x86_64__) || defined(__arm__)
1706 if (IsSystemVSharedMemory(sysno))
1707 return ErrorCode(ErrorCode::ERR_ALLOWED);
1708 #endif
1709 #if defined(__i386__)
1710 if (IsSystemVIpc(sysno))
1711 return ErrorCode(ErrorCode::ERR_ALLOWED);
1712 #endif
1715 // Default on the baseline policy.
1716 return BaselinePolicy(sandbox, sysno);
1720 ErrorCode BlacklistDebugAndNumaPolicy(Sandbox* sandbox, int sysno, void*) {
1721 if (!Sandbox::IsValidSyscallNumber(sysno)) {
1722 // TODO(jln) we should not have to do that in a trivial policy.
1723 return ErrorCode(ENOSYS);
1726 if (IsDebug(sysno) || IsNuma(sysno))
1727 return sandbox->Trap(CrashSIGSYS_Handler, NULL);
1729 return ErrorCode(ErrorCode::ERR_ALLOWED);
1732 // Allow all syscalls.
1733 // This will still deny x32 or IA32 calls in 64 bits mode or
1734 // 64 bits system calls in compatibility mode.
1735 ErrorCode AllowAllPolicy(Sandbox*, int sysno, void*) {
1736 if (!Sandbox::IsValidSyscallNumber(sysno)) {
1737 // TODO(jln) we should not have to do that in a trivial policy.
1738 return ErrorCode(ENOSYS);
1739 } else {
1740 return ErrorCode(ErrorCode::ERR_ALLOWED);
1744 // If a BPF policy is engaged for |process_type|, run a few sanity checks.
1745 void RunSandboxSanityChecks(const std::string& process_type) {
1746 if (process_type == switches::kRendererProcess ||
1747 process_type == switches::kWorkerProcess ||
1748 process_type == switches::kGpuProcess ||
1749 process_type == switches::kPpapiPluginProcess) {
1750 int syscall_ret;
1751 errno = 0;
1753 // Without the sandbox, this would EBADF.
1754 syscall_ret = fchmod(-1, 07777);
1755 CHECK_EQ(-1, syscall_ret);
1756 CHECK_EQ(EPERM, errno);
1758 // Run most of the sanity checks only in DEBUG mode to avoid a perf.
1759 // impact.
1760 #if !defined(NDEBUG)
1761 // open() must be restricted.
1762 syscall_ret = open("/etc/passwd", O_RDONLY);
1763 CHECK_EQ(-1, syscall_ret);
1764 CHECK_EQ(kFSDeniedErrno, errno);
1766 // We should never allow the creation of netlink sockets.
1767 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0);
1768 CHECK_EQ(-1, syscall_ret);
1769 CHECK_EQ(EPERM, errno);
1770 #endif // !defined(NDEBUG)
1774 bool EnableGpuBrokerPolicyCallback() {
1775 StartSandboxWithPolicy(GpuBrokerProcessPolicy, NULL);
1776 return true;
1779 bool EnableArmGpuBrokerPolicyCallback() {
1780 StartSandboxWithPolicy(ArmGpuBrokerProcessPolicy, NULL);
1781 return true;
1784 // Files needed by the ARM GPU userspace.
1785 static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
1786 static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
1788 void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist,
1789 std::vector<std::string>* write_whitelist) {
1790 // Device file needed by the ARM GPU userspace.
1791 static const char kMali0Path[] = "/dev/mali0";
1793 // Devices needed for video decode acceleration on ARM.
1794 static const char kDevMfcDecPath[] = "/dev/mfc-dec";
1795 static const char kDevGsc1Path[] = "/dev/gsc1";
1797 // Devices needed for video encode acceleration on ARM.
1798 static const char kDevMfcEncPath[] = "/dev/mfc-enc";
1800 read_whitelist->push_back(kMali0Path);
1801 read_whitelist->push_back(kDevMfcDecPath);
1802 read_whitelist->push_back(kDevGsc1Path);
1803 read_whitelist->push_back(kDevMfcEncPath);
1805 write_whitelist->push_back(kMali0Path);
1806 write_whitelist->push_back(kDevMfcDecPath);
1807 write_whitelist->push_back(kDevGsc1Path);
1808 write_whitelist->push_back(kDevMfcEncPath);
1811 void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist,
1812 std::vector<std::string>* write_whitelist) {
1813 // Device files needed by the Tegra GPU userspace.
1814 static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl";
1815 static const char kDevNvhostGr2dPath[] = "/dev/nvhost-gr2d";
1816 static const char kDevNvhostGr3dPath[] = "/dev/nvhost-gr3d";
1817 static const char kDevNvhostIspPath[] = "/dev/nvhost-isp";
1818 static const char kDevNvhostViPath[] = "/dev/nvhost-vi";
1819 static const char kDevNvmapPath[] = "/dev/nvmap";
1820 static const char kDevTegraSemaPath[] = "/dev/tegra_sema";
1822 read_whitelist->push_back(kDevNvhostCtrlPath);
1823 read_whitelist->push_back(kDevNvhostGr2dPath);
1824 read_whitelist->push_back(kDevNvhostGr3dPath);
1825 read_whitelist->push_back(kDevNvhostIspPath);
1826 read_whitelist->push_back(kDevNvhostViPath);
1827 read_whitelist->push_back(kDevNvmapPath);
1828 read_whitelist->push_back(kDevTegraSemaPath);
1830 write_whitelist->push_back(kDevNvhostCtrlPath);
1831 write_whitelist->push_back(kDevNvhostGr2dPath);
1832 write_whitelist->push_back(kDevNvhostGr3dPath);
1833 write_whitelist->push_back(kDevNvhostIspPath);
1834 write_whitelist->push_back(kDevNvhostViPath);
1835 write_whitelist->push_back(kDevNvmapPath);
1836 write_whitelist->push_back(kDevTegraSemaPath);
1839 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist,
1840 std::vector<std::string>* write_whitelist) {
1841 // On ARM we're enabling the sandbox before the X connection is made,
1842 // so we need to allow access to |.Xauthority|.
1843 static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
1844 static const char kLdSoCache[] = "/etc/ld.so.cache";
1846 read_whitelist->push_back(kXAuthorityPath);
1847 read_whitelist->push_back(kLdSoCache);
1848 read_whitelist->push_back(kLibGlesPath);
1849 read_whitelist->push_back(kLibEglPath);
1851 AddArmMaliGpuWhitelist(read_whitelist, write_whitelist);
1852 AddArmTegraGpuWhitelist(read_whitelist, write_whitelist);
1855 // Start a broker process to handle open() inside the sandbox.
1856 void InitGpuBrokerProcess(Sandbox::EvaluateSyscall gpu_policy,
1857 BrokerProcess** broker_process) {
1858 static const char kDriRcPath[] = "/etc/drirc";
1859 static const char kDriCard0Path[] = "/dev/dri/card0";
1861 CHECK(broker_process);
1862 CHECK(*broker_process == NULL);
1864 bool (*sandbox_callback)(void) = NULL;
1866 // All GPU process policies need these files brokered out.
1867 std::vector<std::string> read_whitelist;
1868 read_whitelist.push_back(kDriCard0Path);
1869 read_whitelist.push_back(kDriRcPath);
1871 std::vector<std::string> write_whitelist;
1872 write_whitelist.push_back(kDriCard0Path);
1874 if (gpu_policy == ArmGpuProcessPolicy ||
1875 gpu_policy == ArmGpuProcessPolicyWithShmat) {
1876 // We shouldn't be using this policy on non-ARM architectures.
1877 CHECK(IsArchitectureArm());
1878 AddArmGpuWhitelist(&read_whitelist, &write_whitelist);
1879 sandbox_callback = EnableArmGpuBrokerPolicyCallback;
1880 } else if (gpu_policy == GpuProcessPolicy) {
1881 sandbox_callback = EnableGpuBrokerPolicyCallback;
1882 } else {
1883 // We shouldn't be initializing a GPU broker process without a GPU process
1884 // policy.
1885 NOTREACHED();
1888 *broker_process = new BrokerProcess(kFSDeniedErrno,
1889 read_whitelist, write_whitelist);
1890 // Initialize the broker process and give it a sandbox callback.
1891 CHECK((*broker_process)->Init(sandbox_callback));
1894 // Warms up/preloads resources needed by the policies.
1895 // Eventually start a broker process and return it in broker_process.
1896 void WarmupPolicy(Sandbox::EvaluateSyscall policy,
1897 BrokerProcess** broker_process) {
1898 if (policy == GpuProcessPolicy) {
1899 // Create a new broker process.
1900 InitGpuBrokerProcess(policy, broker_process);
1902 if (IsArchitectureX86_64() || IsArchitectureI386()) {
1903 // Accelerated video decode dlopen()'s a shared object
1904 // inside the sandbox, so preload it now.
1905 if (IsAcceleratedVideoDecodeEnabled()) {
1906 const char* I965DrvVideoPath = NULL;
1908 if (IsArchitectureX86_64()) {
1909 I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so";
1910 } else if (IsArchitectureI386()) {
1911 I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so";
1914 dlopen(I965DrvVideoPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1917 } else if (policy == ArmGpuProcessPolicy ||
1918 policy == ArmGpuProcessPolicyWithShmat) {
1919 // Create a new broker process.
1920 InitGpuBrokerProcess(policy, broker_process);
1922 // Preload the Tegra libraries.
1923 dlopen("/usr/lib/libnvrm.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1924 dlopen("/usr/lib/libnvrm_graphics.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1925 dlopen("/usr/lib/libnvos.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1926 dlopen("/usr/lib/libnvddk_2d.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1927 dlopen("/usr/lib/libardrv_dynamic.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1928 dlopen("/usr/lib/libnvwsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1929 dlopen("/usr/lib/libnvglsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1930 dlopen("/usr/lib/libcgdrv.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1934 Sandbox::EvaluateSyscall GetProcessSyscallPolicy(
1935 const CommandLine& command_line,
1936 const std::string& process_type) {
1937 if (process_type == switches::kGpuProcess) {
1938 // On Chrome OS ARM, we need a specific GPU process policy.
1939 if (IsChromeOS() && IsArchitectureArm()) {
1940 if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm))
1941 return ArmGpuProcessPolicyWithShmat;
1942 else
1943 return ArmGpuProcessPolicy;
1945 else
1946 return GpuProcessPolicy;
1949 if (process_type == switches::kPpapiPluginProcess) {
1950 // TODO(jln): figure out what to do with non-Flash PPAPI
1951 // out-of-process plug-ins.
1952 return FlashProcessPolicy;
1955 if (process_type == switches::kRendererProcess ||
1956 process_type == switches::kWorkerProcess) {
1957 return RendererOrWorkerProcessPolicy;
1960 if (process_type == switches::kUtilityProcess) {
1961 // TODO(jorgelo): review sandbox initialization in utility_main.cc if we
1962 // change this policy.
1963 return BlacklistDebugAndNumaPolicy;
1966 NOTREACHED();
1967 // This will be our default if we need one.
1968 return AllowAllPolicy;
1971 // broker_process can be NULL if there is no need for one.
1972 void StartSandboxWithPolicy(Sandbox::EvaluateSyscall syscall_policy,
1973 BrokerProcess* broker_process) {
1974 // Starting the sandbox is a one-way operation. The kernel doesn't allow
1975 // us to unload a sandbox policy after it has been started. Nonetheless,
1976 // in order to make the use of the "Sandbox" object easier, we allow for
1977 // the object to be destroyed after the sandbox has been started. Note that
1978 // doing so does not stop the sandbox.
1979 Sandbox sandbox;
1980 sandbox.SetSandboxPolicy(syscall_policy, broker_process);
1981 sandbox.StartSandbox();
1984 // Initialize the seccomp-bpf sandbox.
1985 bool StartBpfSandbox(const CommandLine& command_line,
1986 const std::string& process_type) {
1987 Sandbox::EvaluateSyscall syscall_policy =
1988 GetProcessSyscallPolicy(command_line, process_type);
1990 BrokerProcess* broker_process = NULL;
1991 // Warm up resources needed by the policy we're about to enable and
1992 // eventually start a broker process.
1993 WarmupPolicy(syscall_policy, &broker_process);
1995 StartSandboxWithPolicy(syscall_policy, broker_process);
1997 RunSandboxSanityChecks(process_type);
1999 return true;
2002 } // namespace
2004 #endif // SECCOMP_BPF_SANDBOX
2006 namespace content {
2008 // Is seccomp BPF globally enabled?
2009 bool SandboxSeccompBpf::IsSeccompBpfDesired() {
2010 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2011 if (!command_line.HasSwitch(switches::kNoSandbox) &&
2012 !command_line.HasSwitch(switches::kDisableSeccompFilterSandbox)) {
2013 return true;
2014 } else {
2015 return false;
2019 bool SandboxSeccompBpf::ShouldEnableSeccompBpf(
2020 const std::string& process_type) {
2021 #if defined(SECCOMP_BPF_SANDBOX)
2022 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2023 if (process_type == switches::kGpuProcess)
2024 return !command_line.HasSwitch(switches::kDisableGpuSandbox);
2026 return true;
2027 #endif // SECCOMP_BPF_SANDBOX
2028 return false;
2031 bool SandboxSeccompBpf::SupportsSandbox() {
2032 #if defined(SECCOMP_BPF_SANDBOX)
2033 // TODO(jln): pass the saved proc_fd_ from the LinuxSandbox singleton
2034 // here.
2035 Sandbox::SandboxStatus bpf_sandbox_status =
2036 Sandbox::SupportsSeccompSandbox(-1);
2037 // Kernel support is what we are interested in here. Other status
2038 // such as STATUS_UNAVAILABLE (has threads) still indicate kernel support.
2039 // We make this a negative check, since if there is a bug, we would rather
2040 // "fail closed" (expect a sandbox to be available and try to start it).
2041 if (bpf_sandbox_status != Sandbox::STATUS_UNSUPPORTED) {
2042 return true;
2044 #endif
2045 return false;
2048 bool SandboxSeccompBpf::StartSandbox(const std::string& process_type) {
2049 #if defined(SECCOMP_BPF_SANDBOX)
2050 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2052 if (IsSeccompBpfDesired() && // Global switches policy.
2053 ShouldEnableSeccompBpf(process_type) && // Process-specific policy.
2054 SupportsSandbox()) {
2055 // If the kernel supports the sandbox, and if the command line says we
2056 // should enable it, enable it or die.
2057 bool started_sandbox = StartBpfSandbox(command_line, process_type);
2058 CHECK(started_sandbox);
2059 return true;
2061 #endif
2062 return false;
2065 bool SandboxSeccompBpf::StartSandboxWithExternalPolicy(
2066 playground2::BpfSandboxPolicy policy) {
2067 #if defined(SECCOMP_BPF_SANDBOX)
2068 if (IsSeccompBpfDesired() && SupportsSandbox()) {
2069 CHECK(policy);
2070 StartSandboxWithPolicy(policy, NULL);
2071 return true;
2073 #endif // defined(SECCOMP_BPF_SANDBOX)
2074 return false;
2077 #if defined(SECCOMP_BPF_SANDBOX)
2078 playground2::BpfSandboxPolicyCallback SandboxSeccompBpf::GetBaselinePolicy() {
2079 return base::Bind(&BaselinePolicyWithAux);
2081 #endif // defined(SECCOMP_BPF_SANDBOX)
2083 } // namespace content