Make developerPrivate API available in stable.
[chromium-blink-merge.git] / content / common / sandbox_seccomp_bpf_linux.cc
blob1ff54e760bcee53e2a4329f6b5a5dc2e62f1ea23
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 ErrorCode BaselinePolicy(Sandbox* sandbox, int sysno) {
1407 if (IsBaselinePolicyAllowed(sysno)) {
1408 return ErrorCode(ErrorCode::ERR_ALLOWED);
1411 #if defined(__x86_64__) || defined(__arm__)
1412 if (sysno == __NR_socketpair) {
1413 // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen.
1414 COMPILE_ASSERT(AF_UNIX == PF_UNIX, af_unix_pf_unix_different);
1415 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, AF_UNIX,
1416 ErrorCode(ErrorCode::ERR_ALLOWED),
1417 sandbox->Trap(CrashSIGSYS_Handler, NULL));
1419 #endif
1421 if (sysno == __NR_madvise) {
1422 // Only allow MADV_DONTNEED (aka MADV_FREE).
1423 return sandbox->Cond(2, ErrorCode::TP_32BIT,
1424 ErrorCode::OP_EQUAL, MADV_DONTNEED,
1425 ErrorCode(ErrorCode::ERR_ALLOWED),
1426 ErrorCode(EPERM));
1429 #if defined(__i386__) || defined(__x86_64__)
1430 if (sysno == __NR_mmap)
1431 return RestrictMmapFlags(sandbox);
1432 #endif
1434 #if defined(__i386__) || defined(__arm__)
1435 if (sysno == __NR_mmap2)
1436 return RestrictMmapFlags(sandbox);
1437 #endif
1439 if (sysno == __NR_mprotect)
1440 return RestrictMprotectFlags(sandbox);
1442 if (sysno == __NR_fcntl)
1443 return RestrictFcntlCommands(sandbox);
1445 #if defined(__i386__) || defined(__arm__)
1446 if (sysno == __NR_fcntl64)
1447 return RestrictFcntlCommands(sandbox);
1448 #endif
1450 if (IsFileSystem(sysno) || IsCurrentDirectory(sysno)) {
1451 return ErrorCode(EPERM);
1454 if (IsAnySystemV(sysno)) {
1455 return ErrorCode(EPERM);
1458 if (IsUmask(sysno) || IsDeniedFileSystemAccessViaFd(sysno) ||
1459 IsDeniedGetOrModifySocket(sysno)) {
1460 return ErrorCode(EPERM);
1463 #if defined(__i386__)
1464 if (IsSocketCall(sysno))
1465 return RestrictSocketcallCommand(sandbox);
1466 #endif
1468 if (IsBaselinePolicyWatched(sysno)) {
1469 // Previously unseen syscalls. TODO(jln): some of these should
1470 // be denied gracefully right away.
1471 return sandbox->Trap(CrashSIGSYS_Handler, NULL);
1473 // In any other case crash the program with our SIGSYS handler.
1474 return sandbox->Trap(CrashSIGSYS_Handler, NULL);
1477 // The BaselinePolicy only takes two arguments. BaselinePolicyWithAux
1478 // allows us to conform to the BPF compiler's policy type.
1479 ErrorCode BaselinePolicyWithAux(Sandbox* sandbox, int sysno, void* aux) {
1480 CHECK(!aux);
1481 return BaselinePolicy(sandbox, sysno);
1484 // Main policy for x86_64/i386. Extended by ArmGpuProcessPolicy.
1485 ErrorCode GpuProcessPolicy(Sandbox* sandbox, int sysno,
1486 void* broker_process) {
1487 switch (sysno) {
1488 case __NR_ioctl:
1489 #if defined(__i386__) || defined(__x86_64__)
1490 // The Nvidia driver uses flags not in the baseline policy
1491 // (MAP_LOCKED | MAP_EXECUTABLE | MAP_32BIT)
1492 case __NR_mmap:
1493 #endif
1494 // We also hit this on the linux_chromeos bot but don't yet know what
1495 // weird flags were involved.
1496 case __NR_mprotect:
1497 case __NR_sched_getaffinity:
1498 case __NR_sched_setaffinity:
1499 case __NR_setpriority:
1500 return ErrorCode(ErrorCode::ERR_ALLOWED);
1501 case __NR_access:
1502 case __NR_open:
1503 case __NR_openat:
1504 return sandbox->Trap(GpuSIGSYS_Handler, broker_process);
1505 default:
1506 if (IsEventFd(sysno))
1507 return ErrorCode(ErrorCode::ERR_ALLOWED);
1509 // Default on the baseline policy.
1510 return BaselinePolicy(sandbox, sysno);
1514 // x86_64/i386.
1515 // A GPU broker policy is the same as a GPU policy with open and
1516 // openat allowed.
1517 ErrorCode GpuBrokerProcessPolicy(Sandbox* sandbox, int sysno, void* aux) {
1518 // "aux" would typically be NULL, when called from
1519 // "EnableGpuBrokerPolicyCallBack"
1520 switch (sysno) {
1521 case __NR_access:
1522 case __NR_open:
1523 case __NR_openat:
1524 return ErrorCode(ErrorCode::ERR_ALLOWED);
1525 default:
1526 return GpuProcessPolicy(sandbox, sysno, aux);
1530 // Generic ARM GPU process sandbox, inheriting from GpuProcessPolicy.
1531 ErrorCode ArmGpuProcessPolicy(Sandbox* sandbox, int sysno,
1532 void* broker_process) {
1533 switch (sysno) {
1534 #if defined(__arm__)
1535 // ARM GPU sandbox is started earlier so we need to allow networking
1536 // in the sandbox.
1537 case __NR_connect:
1538 case __NR_getpeername:
1539 case __NR_getsockname:
1540 case __NR_sysinfo:
1541 case __NR_uname:
1542 return ErrorCode(ErrorCode::ERR_ALLOWED);
1543 // Allow only AF_UNIX for |domain|.
1544 case __NR_socket:
1545 case __NR_socketpair:
1546 return sandbox->Cond(0, ErrorCode::TP_32BIT,
1547 ErrorCode::OP_EQUAL, AF_UNIX,
1548 ErrorCode(ErrorCode::ERR_ALLOWED),
1549 ErrorCode(EPERM));
1550 #endif // defined(__arm__)
1551 default:
1552 if (IsAdvancedScheduler(sysno))
1553 return ErrorCode(ErrorCode::ERR_ALLOWED);
1555 // Default to the generic GPU policy.
1556 return GpuProcessPolicy(sandbox, sysno, broker_process);
1560 // Same as above but with shmat allowed, inheriting from GpuProcessPolicy.
1561 ErrorCode ArmGpuProcessPolicyWithShmat(Sandbox* sandbox, int sysno,
1562 void* broker_process) {
1563 #if defined(__arm__)
1564 if (sysno == __NR_shmat)
1565 return ErrorCode(ErrorCode::ERR_ALLOWED);
1566 #endif // defined(__arm__)
1568 return ArmGpuProcessPolicy(sandbox, sysno, broker_process);
1571 // A GPU broker policy is the same as a GPU policy with open and
1572 // openat allowed.
1573 ErrorCode ArmGpuBrokerProcessPolicy(Sandbox* sandbox,
1574 int sysno, void* aux) {
1575 // "aux" would typically be NULL, when called from
1576 // "EnableGpuBrokerPolicyCallBack"
1577 switch (sysno) {
1578 case __NR_access:
1579 case __NR_open:
1580 case __NR_openat:
1581 return ErrorCode(ErrorCode::ERR_ALLOWED);
1582 default:
1583 return ArmGpuProcessPolicy(sandbox, sysno, aux);
1587 // Allow clone(2) for threads.
1588 // Reject fork(2) attempts with EPERM.
1589 // Crash if anything else is attempted.
1590 // Don't restrict on ASAN.
1591 ErrorCode RestrictCloneToThreadsAndEPERMFork(Sandbox* sandbox) {
1592 // Glibc's pthread.
1593 if (!RunningOnASAN()) {
1594 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1595 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
1596 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS |
1597 CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID,
1598 ErrorCode(ErrorCode::ERR_ALLOWED),
1599 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1600 CLONE_PARENT_SETTID | SIGCHLD,
1601 ErrorCode(EPERM),
1602 // ARM
1603 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1604 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD,
1605 ErrorCode(EPERM),
1606 sandbox->Trap(SIGSYSCloneFailure, NULL))));
1607 } else {
1608 return ErrorCode(ErrorCode::ERR_ALLOWED);
1612 ErrorCode RestrictPrctl(Sandbox* sandbox) {
1613 // Allow PR_SET_NAME, PR_SET_DUMPABLE, PR_GET_DUMPABLE. Will need to add
1614 // seccomp compositing in the future.
1615 // PR_SET_PTRACER is used by breakpad but not needed anymore.
1616 return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1617 PR_SET_NAME, ErrorCode(ErrorCode::ERR_ALLOWED),
1618 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1619 PR_SET_DUMPABLE, ErrorCode(ErrorCode::ERR_ALLOWED),
1620 sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
1621 PR_GET_DUMPABLE, ErrorCode(ErrorCode::ERR_ALLOWED),
1622 sandbox->Trap(SIGSYSPrctlFailure, NULL))));
1625 ErrorCode RestrictIoctl(Sandbox* sandbox) {
1626 // Allow TCGETS and FIONREAD, trap to SIGSYSIoctlFailure otherwise.
1627 return sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, TCGETS,
1628 ErrorCode(ErrorCode::ERR_ALLOWED),
1629 sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, FIONREAD,
1630 ErrorCode(ErrorCode::ERR_ALLOWED),
1631 sandbox->Trap(SIGSYSIoctlFailure, NULL)));
1634 ErrorCode RendererOrWorkerProcessPolicy(Sandbox* sandbox, int sysno, void*) {
1635 switch (sysno) {
1636 case __NR_clone:
1637 return RestrictCloneToThreadsAndEPERMFork(sandbox);
1638 case __NR_ioctl:
1639 return RestrictIoctl(sandbox);
1640 case __NR_prctl:
1641 return RestrictPrctl(sandbox);
1642 // Allow the system calls below.
1643 case __NR_fdatasync:
1644 case __NR_fsync:
1645 case __NR_getpriority:
1646 #if defined(__i386__) || defined(__x86_64__)
1647 case __NR_getrlimit:
1648 #endif
1649 #if defined(__i386__) || defined(__arm__)
1650 case __NR_ugetrlimit:
1651 #endif
1652 case __NR_mremap: // See crbug.com/149834.
1653 case __NR_pread64:
1654 case __NR_pwrite64:
1655 case __NR_sched_getaffinity:
1656 case __NR_sched_get_priority_max:
1657 case __NR_sched_get_priority_min:
1658 case __NR_sched_getparam:
1659 case __NR_sched_getscheduler:
1660 case __NR_sched_setscheduler:
1661 case __NR_setpriority:
1662 case __NR_sysinfo:
1663 case __NR_times:
1664 case __NR_uname:
1665 return ErrorCode(ErrorCode::ERR_ALLOWED);
1666 case __NR_prlimit64:
1667 return ErrorCode(EPERM); // See crbug.com/160157.
1668 default:
1669 if (IsUsingToolKitGtk()) {
1670 #if defined(__x86_64__) || defined(__arm__)
1671 if (IsSystemVSharedMemory(sysno))
1672 return ErrorCode(ErrorCode::ERR_ALLOWED);
1673 #endif
1674 #if defined(__i386__)
1675 if (IsSystemVIpc(sysno))
1676 return ErrorCode(ErrorCode::ERR_ALLOWED);
1677 #endif
1680 // Default on the baseline policy.
1681 return BaselinePolicy(sandbox, sysno);
1685 ErrorCode FlashProcessPolicy(Sandbox* sandbox, int sysno, void*) {
1686 switch (sysno) {
1687 case __NR_clone:
1688 return RestrictCloneToThreadsAndEPERMFork(sandbox);
1689 case __NR_pread64:
1690 case __NR_pwrite64:
1691 case __NR_sched_get_priority_max:
1692 case __NR_sched_get_priority_min:
1693 case __NR_sched_getaffinity:
1694 case __NR_sched_getparam:
1695 case __NR_sched_getscheduler:
1696 case __NR_sched_setscheduler:
1697 case __NR_times:
1698 return ErrorCode(ErrorCode::ERR_ALLOWED);
1699 case __NR_ioctl:
1700 return ErrorCode(ENOTTY); // Flash Access.
1701 default:
1702 if (IsUsingToolKitGtk()) {
1703 #if defined(__x86_64__) || defined(__arm__)
1704 if (IsSystemVSharedMemory(sysno))
1705 return ErrorCode(ErrorCode::ERR_ALLOWED);
1706 #endif
1707 #if defined(__i386__)
1708 if (IsSystemVIpc(sysno))
1709 return ErrorCode(ErrorCode::ERR_ALLOWED);
1710 #endif
1713 // Default on the baseline policy.
1714 return BaselinePolicy(sandbox, sysno);
1718 ErrorCode BlacklistDebugAndNumaPolicy(Sandbox* sandbox, int sysno, void*) {
1719 if (!Sandbox::IsValidSyscallNumber(sysno)) {
1720 // TODO(jln) we should not have to do that in a trivial policy.
1721 return ErrorCode(ENOSYS);
1724 if (IsDebug(sysno) || IsNuma(sysno))
1725 return sandbox->Trap(CrashSIGSYS_Handler, NULL);
1727 return ErrorCode(ErrorCode::ERR_ALLOWED);
1730 // Allow all syscalls.
1731 // This will still deny x32 or IA32 calls in 64 bits mode or
1732 // 64 bits system calls in compatibility mode.
1733 ErrorCode AllowAllPolicy(Sandbox*, int sysno, void*) {
1734 if (!Sandbox::IsValidSyscallNumber(sysno)) {
1735 // TODO(jln) we should not have to do that in a trivial policy.
1736 return ErrorCode(ENOSYS);
1737 } else {
1738 return ErrorCode(ErrorCode::ERR_ALLOWED);
1742 // If a BPF policy is engaged for |process_type|, run a few sanity checks.
1743 void RunSandboxSanityChecks(const std::string& process_type) {
1744 if (process_type == switches::kRendererProcess ||
1745 process_type == switches::kWorkerProcess ||
1746 process_type == switches::kGpuProcess ||
1747 process_type == switches::kPpapiPluginProcess) {
1748 int syscall_ret;
1749 errno = 0;
1751 // Without the sandbox, this would EBADF.
1752 syscall_ret = fchmod(-1, 07777);
1753 CHECK_EQ(-1, syscall_ret);
1754 CHECK_EQ(EPERM, errno);
1756 // Run most of the sanity checks only in DEBUG mode to avoid a perf.
1757 // impact.
1758 #if !defined(NDEBUG)
1759 // open() must be restricted.
1760 syscall_ret = open("/etc/passwd", O_RDONLY);
1761 CHECK_EQ(-1, syscall_ret);
1762 CHECK_EQ(EPERM, errno);
1764 // We should never allow the creation of netlink sockets.
1765 syscall_ret = socket(AF_NETLINK, SOCK_DGRAM, 0);
1766 CHECK_EQ(-1, syscall_ret);
1767 CHECK_EQ(EPERM, errno);
1768 #endif // !defined(NDEBUG)
1772 bool EnableGpuBrokerPolicyCallback() {
1773 StartSandboxWithPolicy(GpuBrokerProcessPolicy, NULL);
1774 return true;
1777 bool EnableArmGpuBrokerPolicyCallback() {
1778 StartSandboxWithPolicy(ArmGpuBrokerProcessPolicy, NULL);
1779 return true;
1782 // Files needed by the ARM GPU userspace.
1783 static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
1784 static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
1786 void AddArmMaliGpuWhitelist(std::vector<std::string>* read_whitelist,
1787 std::vector<std::string>* write_whitelist) {
1788 // Device file needed by the ARM GPU userspace.
1789 static const char kMali0Path[] = "/dev/mali0";
1791 // Devices needed for video decode acceleration on ARM.
1792 static const char kDevMfcDecPath[] = "/dev/mfc-dec";
1793 static const char kDevGsc1Path[] = "/dev/gsc1";
1795 // Devices needed for video encode acceleration on ARM.
1796 static const char kDevMfcEncPath[] = "/dev/mfc-enc";
1798 read_whitelist->push_back(kMali0Path);
1799 read_whitelist->push_back(kDevMfcDecPath);
1800 read_whitelist->push_back(kDevGsc1Path);
1801 read_whitelist->push_back(kDevMfcEncPath);
1803 write_whitelist->push_back(kMali0Path);
1804 write_whitelist->push_back(kDevMfcDecPath);
1805 write_whitelist->push_back(kDevGsc1Path);
1806 write_whitelist->push_back(kDevMfcEncPath);
1809 void AddArmTegraGpuWhitelist(std::vector<std::string>* read_whitelist,
1810 std::vector<std::string>* write_whitelist) {
1811 // Device files needed by the Tegra GPU userspace.
1812 static const char kDevNvhostCtrlPath[] = "/dev/nvhost-ctrl";
1813 static const char kDevNvhostGr2dPath[] = "/dev/nvhost-gr2d";
1814 static const char kDevNvhostGr3dPath[] = "/dev/nvhost-gr3d";
1815 static const char kDevNvhostIspPath[] = "/dev/nvhost-isp";
1816 static const char kDevNvhostViPath[] = "/dev/nvhost-vi";
1817 static const char kDevNvmapPath[] = "/dev/nvmap";
1818 static const char kDevTegraSemaPath[] = "/dev/tegra_sema";
1820 read_whitelist->push_back(kDevNvhostCtrlPath);
1821 read_whitelist->push_back(kDevNvhostGr2dPath);
1822 read_whitelist->push_back(kDevNvhostGr3dPath);
1823 read_whitelist->push_back(kDevNvhostIspPath);
1824 read_whitelist->push_back(kDevNvhostViPath);
1825 read_whitelist->push_back(kDevNvmapPath);
1826 read_whitelist->push_back(kDevTegraSemaPath);
1828 write_whitelist->push_back(kDevNvhostCtrlPath);
1829 write_whitelist->push_back(kDevNvhostGr2dPath);
1830 write_whitelist->push_back(kDevNvhostGr3dPath);
1831 write_whitelist->push_back(kDevNvhostIspPath);
1832 write_whitelist->push_back(kDevNvhostViPath);
1833 write_whitelist->push_back(kDevNvmapPath);
1834 write_whitelist->push_back(kDevTegraSemaPath);
1837 void AddArmGpuWhitelist(std::vector<std::string>* read_whitelist,
1838 std::vector<std::string>* write_whitelist) {
1839 // On ARM we're enabling the sandbox before the X connection is made,
1840 // so we need to allow access to |.Xauthority|.
1841 static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
1842 static const char kLdSoCache[] = "/etc/ld.so.cache";
1844 read_whitelist->push_back(kXAuthorityPath);
1845 read_whitelist->push_back(kLdSoCache);
1846 read_whitelist->push_back(kLibGlesPath);
1847 read_whitelist->push_back(kLibEglPath);
1849 AddArmMaliGpuWhitelist(read_whitelist, write_whitelist);
1850 AddArmTegraGpuWhitelist(read_whitelist, write_whitelist);
1853 // Start a broker process to handle open() inside the sandbox.
1854 void InitGpuBrokerProcess(Sandbox::EvaluateSyscall gpu_policy,
1855 BrokerProcess** broker_process) {
1856 static const char kDriRcPath[] = "/etc/drirc";
1857 static const char kDriCard0Path[] = "/dev/dri/card0";
1859 CHECK(broker_process);
1860 CHECK(*broker_process == NULL);
1862 bool (*sandbox_callback)(void) = NULL;
1864 // All GPU process policies need these files brokered out.
1865 std::vector<std::string> read_whitelist;
1866 read_whitelist.push_back(kDriCard0Path);
1867 read_whitelist.push_back(kDriRcPath);
1869 std::vector<std::string> write_whitelist;
1870 write_whitelist.push_back(kDriCard0Path);
1872 if (gpu_policy == ArmGpuProcessPolicy ||
1873 gpu_policy == ArmGpuProcessPolicyWithShmat) {
1874 // We shouldn't be using this policy on non-ARM architectures.
1875 CHECK(IsArchitectureArm());
1876 AddArmGpuWhitelist(&read_whitelist, &write_whitelist);
1877 sandbox_callback = EnableArmGpuBrokerPolicyCallback;
1878 } else if (gpu_policy == GpuProcessPolicy) {
1879 sandbox_callback = EnableGpuBrokerPolicyCallback;
1880 } else {
1881 // We shouldn't be initializing a GPU broker process without a GPU process
1882 // policy.
1883 NOTREACHED();
1886 *broker_process = new BrokerProcess(read_whitelist, write_whitelist);
1887 // Initialize the broker process and give it a sandbox callback.
1888 CHECK((*broker_process)->Init(sandbox_callback));
1891 // Warms up/preloads resources needed by the policies.
1892 // Eventually start a broker process and return it in broker_process.
1893 void WarmupPolicy(Sandbox::EvaluateSyscall policy,
1894 BrokerProcess** broker_process) {
1895 if (policy == GpuProcessPolicy) {
1896 // Create a new broker process.
1897 InitGpuBrokerProcess(policy, broker_process);
1899 if (IsArchitectureX86_64() || IsArchitectureI386()) {
1900 // Accelerated video decode dlopen()'s a shared object
1901 // inside the sandbox, so preload it now.
1902 if (IsAcceleratedVideoDecodeEnabled()) {
1903 const char* I965DrvVideoPath = NULL;
1905 if (IsArchitectureX86_64()) {
1906 I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so";
1907 } else if (IsArchitectureI386()) {
1908 I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so";
1911 dlopen(I965DrvVideoPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1914 } else if (policy == ArmGpuProcessPolicy ||
1915 policy == ArmGpuProcessPolicyWithShmat) {
1916 // Create a new broker process.
1917 InitGpuBrokerProcess(policy, broker_process);
1919 // Preload the GL libraries. These are in the read whitelist but we have to
1920 // preload them anyways to work around ld.so bugs. See crbug.com/268439.
1921 dlopen(kLibGlesPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1922 dlopen(kLibEglPath, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1924 // Preload the Tegra libraries.
1925 dlopen("/usr/lib/libnvrm.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1926 dlopen("/usr/lib/libnvrm_graphics.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1927 dlopen("/usr/lib/libnvos.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1928 dlopen("/usr/lib/libnvddk_2d.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1929 dlopen("/usr/lib/libardrv_dynamic.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1930 dlopen("/usr/lib/libnvwsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1931 dlopen("/usr/lib/libnvglsi.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1932 dlopen("/usr/lib/libcgdrv.so", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
1936 Sandbox::EvaluateSyscall GetProcessSyscallPolicy(
1937 const CommandLine& command_line,
1938 const std::string& process_type) {
1939 if (process_type == switches::kGpuProcess) {
1940 // On Chrome OS ARM, we need a specific GPU process policy.
1941 if (IsChromeOS() && IsArchitectureArm()) {
1942 if (command_line.HasSwitch(switches::kGpuSandboxAllowSysVShm))
1943 return ArmGpuProcessPolicyWithShmat;
1944 else
1945 return ArmGpuProcessPolicy;
1947 else
1948 return GpuProcessPolicy;
1951 if (process_type == switches::kPpapiPluginProcess) {
1952 // TODO(jln): figure out what to do with non-Flash PPAPI
1953 // out-of-process plug-ins.
1954 return FlashProcessPolicy;
1957 if (process_type == switches::kRendererProcess ||
1958 process_type == switches::kWorkerProcess) {
1959 return RendererOrWorkerProcessPolicy;
1962 if (process_type == switches::kUtilityProcess) {
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