5#if defined(HAVE_CONFIG_H)
11#if defined(USE_SYSCALL_SANDBOX)
26#include <linux/audit.h>
27#include <linux/filter.h>
28#include <linux/seccomp.h>
29#include <linux/unistd.h>
36bool g_syscall_sandbox_enabled{
false};
37bool g_syscall_sandbox_log_violation_before_terminating{
false};
39#if !defined(__x86_64__)
40#error Syscall sandbox is an experimental feature currently available only under Linux x86-64.
43#ifndef SECCOMP_RET_KILL_PROCESS
44#define SECCOMP_RET_KILL_PROCESS 0x80000000U
52#define __NR_clone3 435
60#define __NR_getrandom 318
63#ifndef __NR_membarrier
64#define __NR_membarrier 324
67#ifndef __NR_copy_file_range
68#define __NR_copy_file_range 326
99const std::map<uint32_t, std::string> LINUX_SYSCALLS{
100 {__NR_accept,
"accept"},
101 {__NR_accept4,
"accept4"},
102 {__NR_access,
"access"},
104 {__NR_add_key,
"add_key"},
105 {__NR_adjtimex,
"adjtimex"},
106 {__NR_afs_syscall,
"afs_syscall"},
107 {__NR_alarm,
"alarm"},
108 {__NR_arch_prctl,
"arch_prctl"},
112 {__NR_capget,
"capget"},
113 {__NR_capset,
"capset"},
114 {__NR_chdir,
"chdir"},
115 {__NR_chmod,
"chmod"},
116 {__NR_chown,
"chown"},
117 {__NR_chroot,
"chroot"},
118 {__NR_clock_adjtime,
"clock_adjtime"},
119 {__NR_clock_getres,
"clock_getres"},
120 {__NR_clock_gettime,
"clock_gettime"},
121 {__NR_clock_nanosleep,
"clock_nanosleep"},
122 {__NR_clock_settime,
"clock_settime"},
123 {__NR_clone,
"clone"},
124 {__NR_clone3,
"clone3"},
125 {__NR_close,
"close"},
126 {__NR_connect,
"connect"},
127 {__NR_copy_file_range,
"copy_file_range"},
128 {__NR_creat,
"creat"},
129 {__NR_create_module,
"create_module"},
130 {__NR_delete_module,
"delete_module"},
134 {__NR_epoll_create,
"epoll_create"},
135 {__NR_epoll_create1,
"epoll_create1"},
136 {__NR_epoll_ctl,
"epoll_ctl"},
137 {__NR_epoll_ctl_old,
"epoll_ctl_old"},
138 {__NR_epoll_pwait,
"epoll_pwait"},
139 {__NR_epoll_wait,
"epoll_wait"},
140 {__NR_epoll_wait_old,
"epoll_wait_old"},
141 {__NR_eventfd,
"eventfd"},
142 {__NR_eventfd2,
"eventfd2"},
143 {__NR_execve,
"execve"},
144 {__NR_execveat,
"execveat"},
146 {__NR_exit_group,
"exit_group"},
147 {__NR_faccessat,
"faccessat"},
148 {__NR_fadvise64,
"fadvise64"},
149 {__NR_fallocate,
"fallocate"},
150 {__NR_fanotify_init,
"fanotify_init"},
151 {__NR_fanotify_mark,
"fanotify_mark"},
152 {__NR_fchdir,
"fchdir"},
153 {__NR_fchmod,
"fchmod"},
154 {__NR_fchmodat,
"fchmodat"},
155 {__NR_fchown,
"fchown"},
156 {__NR_fchownat,
"fchownat"},
157 {__NR_fcntl,
"fcntl"},
158 {__NR_fdatasync,
"fdatasync"},
159 {__NR_fgetxattr,
"fgetxattr"},
160 {__NR_finit_module,
"finit_module"},
161 {__NR_flistxattr,
"flistxattr"},
162 {__NR_flock,
"flock"},
164 {__NR_fremovexattr,
"fremovexattr"},
165 {__NR_fsetxattr,
"fsetxattr"},
166 {__NR_fstat,
"fstat"},
167 {__NR_fstatfs,
"fstatfs"},
168 {__NR_fsync,
"fsync"},
169 {__NR_ftruncate,
"ftruncate"},
170 {__NR_futex,
"futex"},
171 {__NR_futimesat,
"futimesat"},
172 {__NR_get_kernel_syms,
"get_kernel_syms"},
173 {__NR_get_mempolicy,
"get_mempolicy"},
174 {__NR_get_robust_list,
"get_robust_list"},
175 {__NR_get_thread_area,
"get_thread_area"},
176 {__NR_getcpu,
"getcpu"},
177 {__NR_getcwd,
"getcwd"},
178 {__NR_getdents,
"getdents"},
179 {__NR_getdents64,
"getdents64"},
180 {__NR_getegid,
"getegid"},
181 {__NR_geteuid,
"geteuid"},
182 {__NR_getgid,
"getgid"},
183 {__NR_getgroups,
"getgroups"},
184 {__NR_getitimer,
"getitimer"},
185 {__NR_getpeername,
"getpeername"},
186 {__NR_getpgid,
"getpgid"},
187 {__NR_getpgrp,
"getpgrp"},
188 {__NR_getpid,
"getpid"},
189 {__NR_getpmsg,
"getpmsg"},
190 {__NR_getppid,
"getppid"},
191 {__NR_getpriority,
"getpriority"},
192 {__NR_getrandom,
"getrandom"},
193 {__NR_getresgid,
"getresgid"},
194 {__NR_getresuid,
"getresuid"},
195 {__NR_getrlimit,
"getrlimit"},
196 {__NR_getrusage,
"getrusage"},
197 {__NR_getsid,
"getsid"},
198 {__NR_getsockname,
"getsockname"},
199 {__NR_getsockopt,
"getsockopt"},
200 {__NR_gettid,
"gettid"},
201 {__NR_gettimeofday,
"gettimeofday"},
202 {__NR_getuid,
"getuid"},
203 {__NR_getxattr,
"getxattr"},
204 {__NR_init_module,
"init_module"},
205 {__NR_inotify_add_watch,
"inotify_add_watch"},
206 {__NR_inotify_init,
"inotify_init"},
207 {__NR_inotify_init1,
"inotify_init1"},
208 {__NR_inotify_rm_watch,
"inotify_rm_watch"},
209 {__NR_io_cancel,
"io_cancel"},
210 {__NR_io_destroy,
"io_destroy"},
211 {__NR_io_getevents,
"io_getevents"},
212 {__NR_io_setup,
"io_setup"},
213 {__NR_io_submit,
"io_submit"},
214 {__NR_ioctl,
"ioctl"},
215 {__NR_ioperm,
"ioperm"},
217 {__NR_ioprio_get,
"ioprio_get"},
218 {__NR_ioprio_set,
"ioprio_set"},
220 {__NR_kexec_file_load,
"kexec_file_load"},
221 {__NR_kexec_load,
"kexec_load"},
222 {__NR_keyctl,
"keyctl"},
224 {__NR_lchown,
"lchown"},
225 {__NR_lgetxattr,
"lgetxattr"},
227 {__NR_linkat,
"linkat"},
228 {__NR_listen,
"listen"},
229 {__NR_listxattr,
"listxattr"},
230 {__NR_llistxattr,
"llistxattr"},
231 {__NR_lookup_dcookie,
"lookup_dcookie"},
232 {__NR_lremovexattr,
"lremovexattr"},
233 {__NR_lseek,
"lseek"},
234 {__NR_lsetxattr,
"lsetxattr"},
235 {__NR_lstat,
"lstat"},
236 {__NR_madvise,
"madvise"},
237 {__NR_mbind,
"mbind"},
238 {__NR_membarrier,
"membarrier"},
239 {__NR_memfd_create,
"memfd_create"},
240 {__NR_migrate_pages,
"migrate_pages"},
241 {__NR_mincore,
"mincore"},
242 {__NR_mkdir,
"mkdir"},
243 {__NR_mkdirat,
"mkdirat"},
244 {__NR_mknod,
"mknod"},
245 {__NR_mknodat,
"mknodat"},
246 {__NR_mlock,
"mlock"},
247 {__NR_mlock2,
"mlock2"},
248 {__NR_mlockall,
"mlockall"},
250 {__NR_modify_ldt,
"modify_ldt"},
251 {__NR_mount,
"mount"},
252 {__NR_move_pages,
"move_pages"},
253 {__NR_mprotect,
"mprotect"},
254 {__NR_mq_getsetattr,
"mq_getsetattr"},
255 {__NR_mq_notify,
"mq_notify"},
256 {__NR_mq_open,
"mq_open"},
257 {__NR_mq_timedreceive,
"mq_timedreceive"},
258 {__NR_mq_timedsend,
"mq_timedsend"},
259 {__NR_mq_unlink,
"mq_unlink"},
260 {__NR_mremap,
"mremap"},
261 {__NR_msgctl,
"msgctl"},
262 {__NR_msgget,
"msgget"},
263 {__NR_msgrcv,
"msgrcv"},
264 {__NR_msgsnd,
"msgsnd"},
265 {__NR_msync,
"msync"},
266 {__NR_munlock,
"munlock"},
267 {__NR_munlockall,
"munlockall"},
268 {__NR_munmap,
"munmap"},
269 {__NR_name_to_handle_at,
"name_to_handle_at"},
270 {__NR_nanosleep,
"nanosleep"},
271 {__NR_newfstatat,
"newfstatat"},
272 {__NR_nfsservctl,
"nfsservctl"},
274 {__NR_open_by_handle_at,
"open_by_handle_at"},
275 {__NR_openat,
"openat"},
276 {__NR_pause,
"pause"},
277 {__NR_perf_event_open,
"perf_event_open"},
278 {__NR_personality,
"personality"},
280 {__NR_pipe2,
"pipe2"},
281 {__NR_pivot_root,
"pivot_root"},
282#ifdef __NR_pkey_alloc
283 {__NR_pkey_alloc,
"pkey_alloc"},
286 {__NR_pkey_free,
"pkey_free"},
288#ifdef __NR_pkey_mprotect
289 {__NR_pkey_mprotect,
"pkey_mprotect"},
292 {__NR_ppoll,
"ppoll"},
293 {__NR_prctl,
"prctl"},
294 {__NR_pread64,
"pread64"},
295 {__NR_preadv,
"preadv"},
297 {__NR_preadv2,
"preadv2"},
299 {__NR_prlimit64,
"prlimit64"},
300 {__NR_process_vm_readv,
"process_vm_readv"},
301 {__NR_process_vm_writev,
"process_vm_writev"},
302 {__NR_pselect6,
"pselect6"},
303 {__NR_ptrace,
"ptrace"},
304 {__NR_putpmsg,
"putpmsg"},
305 {__NR_pwrite64,
"pwrite64"},
306 {__NR_pwritev,
"pwritev"},
308 {__NR_pwritev2,
"pwritev2"},
310 {__NR__sysctl,
"_sysctl"},
311 {__NR_query_module,
"query_module"},
312 {__NR_quotactl,
"quotactl"},
314 {__NR_readahead,
"readahead"},
315 {__NR_readlink,
"readlink"},
316 {__NR_readlinkat,
"readlinkat"},
317 {__NR_readv,
"readv"},
318 {__NR_reboot,
"reboot"},
319 {__NR_recvfrom,
"recvfrom"},
320 {__NR_recvmmsg,
"recvmmsg"},
321 {__NR_recvmsg,
"recvmsg"},
322 {__NR_remap_file_pages,
"remap_file_pages"},
323 {__NR_removexattr,
"removexattr"},
324 {__NR_rename,
"rename"},
325 {__NR_renameat,
"renameat"},
326 {__NR_renameat2,
"renameat2"},
327 {__NR_request_key,
"request_key"},
328 {__NR_restart_syscall,
"restart_syscall"},
329 {__NR_rmdir,
"rmdir"},
330 {__NR_rt_sigaction,
"rt_sigaction"},
331 {__NR_rt_sigpending,
"rt_sigpending"},
332 {__NR_rt_sigprocmask,
"rt_sigprocmask"},
333 {__NR_rt_sigqueueinfo,
"rt_sigqueueinfo"},
334 {__NR_rt_sigreturn,
"rt_sigreturn"},
335 {__NR_rt_sigsuspend,
"rt_sigsuspend"},
336 {__NR_rt_sigtimedwait,
"rt_sigtimedwait"},
337 {__NR_rt_tgsigqueueinfo,
"rt_tgsigqueueinfo"},
338 {__NR_sched_get_priority_max,
"sched_get_priority_max"},
339 {__NR_sched_get_priority_min,
"sched_get_priority_min"},
340 {__NR_sched_getaffinity,
"sched_getaffinity"},
341 {__NR_sched_getattr,
"sched_getattr"},
342 {__NR_sched_getparam,
"sched_getparam"},
343 {__NR_sched_getscheduler,
"sched_getscheduler"},
344 {__NR_sched_rr_get_interval,
"sched_rr_get_interval"},
345 {__NR_sched_setaffinity,
"sched_setaffinity"},
346 {__NR_sched_setattr,
"sched_setattr"},
347 {__NR_sched_setparam,
"sched_setparam"},
348 {__NR_sched_setscheduler,
"sched_setscheduler"},
349 {__NR_sched_yield,
"sched_yield"},
350 {__NR_seccomp,
"seccomp"},
351 {__NR_security,
"security"},
352 {__NR_select,
"select"},
353 {__NR_semctl,
"semctl"},
354 {__NR_semget,
"semget"},
355 {__NR_semop,
"semop"},
356 {__NR_semtimedop,
"semtimedop"},
357 {__NR_sendfile,
"sendfile"},
358 {__NR_sendmmsg,
"sendmmsg"},
359 {__NR_sendmsg,
"sendmsg"},
360 {__NR_sendto,
"sendto"},
361 {__NR_set_mempolicy,
"set_mempolicy"},
362 {__NR_set_robust_list,
"set_robust_list"},
363 {__NR_set_thread_area,
"set_thread_area"},
364 {__NR_set_tid_address,
"set_tid_address"},
365 {__NR_setdomainname,
"setdomainname"},
366 {__NR_setfsgid,
"setfsgid"},
367 {__NR_setfsuid,
"setfsuid"},
368 {__NR_setgid,
"setgid"},
369 {__NR_setgroups,
"setgroups"},
370 {__NR_sethostname,
"sethostname"},
371 {__NR_setitimer,
"setitimer"},
372 {__NR_setns,
"setns"},
373 {__NR_setpgid,
"setpgid"},
374 {__NR_setpriority,
"setpriority"},
375 {__NR_setregid,
"setregid"},
376 {__NR_setresgid,
"setresgid"},
377 {__NR_setresuid,
"setresuid"},
378 {__NR_setreuid,
"setreuid"},
379 {__NR_setrlimit,
"setrlimit"},
380 {__NR_setsid,
"setsid"},
381 {__NR_setsockopt,
"setsockopt"},
382 {__NR_settimeofday,
"settimeofday"},
383 {__NR_setuid,
"setuid"},
384 {__NR_setxattr,
"setxattr"},
385 {__NR_shmat,
"shmat"},
386 {__NR_shmctl,
"shmctl"},
387 {__NR_shmdt,
"shmdt"},
388 {__NR_shmget,
"shmget"},
389 {__NR_shutdown,
"shutdown"},
390 {__NR_sigaltstack,
"sigaltstack"},
391 {__NR_signalfd,
"signalfd"},
392 {__NR_signalfd4,
"signalfd4"},
393 {__NR_socket,
"socket"},
394 {__NR_socketpair,
"socketpair"},
395 {__NR_splice,
"splice"},
397 {__NR_statfs,
"statfs"},
398 {__NR_statx,
"statx"},
399 {__NR_swapoff,
"swapoff"},
400 {__NR_swapon,
"swapon"},
401 {__NR_symlink,
"symlink"},
402 {__NR_symlinkat,
"symlinkat"},
404 {__NR_sync_file_range,
"sync_file_range"},
405 {__NR_syncfs,
"syncfs"},
406 {__NR_sysfs,
"sysfs"},
407 {__NR_sysinfo,
"sysinfo"},
408 {__NR_syslog,
"syslog"},
410 {__NR_tgkill,
"tgkill"},
412 {__NR_timer_create,
"timer_create"},
413 {__NR_timer_delete,
"timer_delete"},
414 {__NR_timer_getoverrun,
"timer_getoverrun"},
415 {__NR_timer_gettime,
"timer_gettime"},
416 {__NR_timer_settime,
"timer_settime"},
417 {__NR_timerfd_create,
"timerfd_create"},
418 {__NR_timerfd_gettime,
"timerfd_gettime"},
419 {__NR_timerfd_settime,
"timerfd_settime"},
420 {__NR_times,
"times"},
421 {__NR_tkill,
"tkill"},
422 {__NR_truncate,
"truncate"},
423 {__NR_tuxcall,
"tuxcall"},
424 {__NR_umask,
"umask"},
425 {__NR_umount2,
"umount2"},
426 {__NR_uname,
"uname"},
427 {__NR_unlink,
"unlink"},
428 {__NR_unlinkat,
"unlinkat"},
429 {__NR_unshare,
"unshare"},
430 {__NR_uselib,
"uselib"},
431 {__NR_userfaultfd,
"userfaultfd"},
432 {__NR_ustat,
"ustat"},
433 {__NR_utime,
"utime"},
434 {__NR_utimensat,
"utimensat"},
435 {__NR_utimes,
"utimes"},
436 {__NR_vfork,
"vfork"},
437 {__NR_vhangup,
"vhangup"},
438 {__NR_vmsplice,
"vmsplice"},
439 {__NR_vserver,
"vserver"},
440 {__NR_wait4,
"wait4"},
441 {__NR_waitid,
"waitid"},
442 {__NR_write,
"write"},
443 {__NR_writev,
"writev"},
446std::string GetLinuxSyscallName(uint32_t syscall_number)
448 const auto element = LINUX_SYSCALLS.find(syscall_number);
449 if (element != LINUX_SYSCALLS.end()) {
450 return element->second;
465void SyscallSandboxDebugSignalHandler(
int, siginfo_t* signal_info,
void* void_signal_context)
472 constexpr int32_t SYS_SECCOMP_SI_CODE{1};
473 assert(signal_info->si_code == SYS_SECCOMP_SI_CODE);
477 const ucontext_t* signal_context =
static_cast<ucontext_t*
>(void_signal_context);
478 assert(signal_context !=
nullptr);
480 std::set_new_handler(std::terminate);
482 const uint32_t syscall_number =
static_cast<uint32_t
>(signal_context->uc_mcontext.gregs[REG_RAX]);
483 const std::string syscall_name = GetLinuxSyscallName(syscall_number);
485 const std::string error_message =
strprintf(
"ERROR: The syscall \"%s\" (syscall number %d) is not allowed by the syscall sandbox in thread \"%s\". Please report.", syscall_name, syscall_number, thread_name);
493bool SetupSyscallSandboxDebugHandler()
495 struct sigaction action = {};
498 sigaddset(&mask, SIGSYS);
499 action.sa_sigaction = &SyscallSandboxDebugSignalHandler;
500 action.sa_flags = SA_SIGINFO;
501 if (sigaction(SIGSYS, &action,
nullptr) < 0) {
504 if (sigprocmask(SIG_UNBLOCK, &mask,
nullptr)) {
510enum class SyscallSandboxAction {
512 INVOKE_SIGNAL_HANDLER,
515class SeccompPolicyBuilder
517 std::set<uint32_t> allowed_syscalls;
520 SeccompPolicyBuilder()
523 AllowAddressSpaceAccess();
531 AllowGlobalProcessEnvironment();
532 AllowGlobalSystemStatus();
533 AllowKernelInternalApi();
534 AllowNetworkSocketInformation();
535 AllowOperationOnExistingFileDescriptor();
538 AllowProcessStartOrDeath();
540 AllowSignalHandling();
545 void AllowAddressSpaceAccess()
547 allowed_syscalls.insert(__NR_brk);
548 allowed_syscalls.insert(__NR_madvise);
549 allowed_syscalls.insert(__NR_membarrier);
550 allowed_syscalls.insert(__NR_mincore);
551 allowed_syscalls.insert(__NR_mlock);
552 allowed_syscalls.insert(__NR_mmap);
553 allowed_syscalls.insert(__NR_mprotect);
554 allowed_syscalls.insert(__NR_mremap);
555 allowed_syscalls.insert(__NR_munlock);
556 allowed_syscalls.insert(__NR_munmap);
561 allowed_syscalls.insert(__NR_epoll_create1);
562 allowed_syscalls.insert(__NR_epoll_ctl);
563 allowed_syscalls.insert(__NR_epoll_pwait);
564 allowed_syscalls.insert(__NR_epoll_wait);
569 allowed_syscalls.insert(__NR_eventfd2);
572 void AllowFileSystem()
574 allowed_syscalls.insert(__NR_access);
575 allowed_syscalls.insert(__NR_chdir);
576 allowed_syscalls.insert(__NR_chmod);
577 allowed_syscalls.insert(__NR_copy_file_range);
578 allowed_syscalls.insert(__NR_fallocate);
579 allowed_syscalls.insert(__NR_fchmod);
580 allowed_syscalls.insert(__NR_fchown);
581 allowed_syscalls.insert(__NR_fdatasync);
582 allowed_syscalls.insert(__NR_flock);
583 allowed_syscalls.insert(__NR_fstat);
584 allowed_syscalls.insert(__NR_newfstatat);
585 allowed_syscalls.insert(__NR_fsync);
586 allowed_syscalls.insert(__NR_ftruncate);
587 allowed_syscalls.insert(__NR_getcwd);
588 allowed_syscalls.insert(__NR_getdents);
589 allowed_syscalls.insert(__NR_getdents64);
590 allowed_syscalls.insert(__NR_lstat);
591 allowed_syscalls.insert(__NR_mkdir);
592 allowed_syscalls.insert(__NR_open);
593 allowed_syscalls.insert(__NR_openat);
594 allowed_syscalls.insert(__NR_readlink);
595 allowed_syscalls.insert(__NR_rename);
596 allowed_syscalls.insert(__NR_rmdir);
597 allowed_syscalls.insert(__NR_stat);
598 allowed_syscalls.insert(__NR_statfs);
599 allowed_syscalls.insert(__NR_statx);
600 allowed_syscalls.insert(__NR_unlink);
605 allowed_syscalls.insert(__NR_futex);
606 allowed_syscalls.insert(__NR_set_robust_list);
609 void AllowGeneralIo()
611 allowed_syscalls.insert(__NR_ioctl);
612 allowed_syscalls.insert(__NR_lseek);
613 allowed_syscalls.insert(__NR_poll);
614 allowed_syscalls.insert(__NR_ppoll);
615 allowed_syscalls.insert(__NR_pread64);
616 allowed_syscalls.insert(__NR_pwrite64);
617 allowed_syscalls.insert(__NR_read);
618 allowed_syscalls.insert(__NR_readv);
619 allowed_syscalls.insert(__NR_recvfrom);
620 allowed_syscalls.insert(__NR_recvmsg);
621 allowed_syscalls.insert(__NR_select);
622 allowed_syscalls.insert(__NR_sendmmsg);
623 allowed_syscalls.insert(__NR_sendmsg);
624 allowed_syscalls.insert(__NR_sendto);
625 allowed_syscalls.insert(__NR_write);
626 allowed_syscalls.insert(__NR_writev);
629 void AllowGetRandom()
631 allowed_syscalls.insert(__NR_getrandom);
634 void AllowGetSimpleId()
636 allowed_syscalls.insert(__NR_getegid);
637 allowed_syscalls.insert(__NR_geteuid);
638 allowed_syscalls.insert(__NR_getgid);
639 allowed_syscalls.insert(__NR_getpgid);
640 allowed_syscalls.insert(__NR_getpid);
641 allowed_syscalls.insert(__NR_getppid);
642 allowed_syscalls.insert(__NR_getresgid);
643 allowed_syscalls.insert(__NR_getresuid);
644 allowed_syscalls.insert(__NR_getsid);
645 allowed_syscalls.insert(__NR_gettid);
646 allowed_syscalls.insert(__NR_getuid);
651 allowed_syscalls.insert(__NR_clock_getres);
652 allowed_syscalls.insert(__NR_clock_gettime);
653 allowed_syscalls.insert(__NR_gettimeofday);
656 void AllowGlobalProcessEnvironment()
658 allowed_syscalls.insert(__NR_getrlimit);
659 allowed_syscalls.insert(__NR_getrusage);
660 allowed_syscalls.insert(__NR_prlimit64);
663 void AllowGlobalSystemStatus()
665 allowed_syscalls.insert(__NR_sysinfo);
666 allowed_syscalls.insert(__NR_uname);
669 void AllowKernelInternalApi()
671 allowed_syscalls.insert(__NR_restart_syscall);
676 allowed_syscalls.insert(__NR_accept);
677 allowed_syscalls.insert(__NR_accept4);
678 allowed_syscalls.insert(__NR_bind);
679 allowed_syscalls.insert(__NR_connect);
680 allowed_syscalls.insert(__NR_listen);
681 allowed_syscalls.insert(__NR_setsockopt);
682 allowed_syscalls.insert(__NR_socket);
683 allowed_syscalls.insert(__NR_socketpair);
686 void AllowNetworkSocketInformation()
688 allowed_syscalls.insert(__NR_getpeername);
689 allowed_syscalls.insert(__NR_getsockname);
690 allowed_syscalls.insert(__NR_getsockopt);
693 void AllowOperationOnExistingFileDescriptor()
695 allowed_syscalls.insert(__NR_close);
696 allowed_syscalls.insert(__NR_dup);
697 allowed_syscalls.insert(__NR_dup2);
698 allowed_syscalls.insert(__NR_fcntl);
699 allowed_syscalls.insert(__NR_shutdown);
704 allowed_syscalls.insert(__NR_pipe);
705 allowed_syscalls.insert(__NR_pipe2);
710 allowed_syscalls.insert(__NR_arch_prctl);
711 allowed_syscalls.insert(__NR_prctl);
714 void AllowProcessStartOrDeath()
716 allowed_syscalls.insert(__NR_clone);
717 allowed_syscalls.insert(__NR_clone3);
718 allowed_syscalls.insert(__NR_exit);
719 allowed_syscalls.insert(__NR_exit_group);
720 allowed_syscalls.insert(__NR_fork);
721 allowed_syscalls.insert(__NR_tgkill);
722 allowed_syscalls.insert(__NR_wait4);
725 void AllowScheduling()
727 allowed_syscalls.insert(__NR_sched_getaffinity);
728 allowed_syscalls.insert(__NR_sched_getparam);
729 allowed_syscalls.insert(__NR_sched_getscheduler);
730 allowed_syscalls.insert(__NR_sched_setscheduler);
731 allowed_syscalls.insert(__NR_sched_yield);
734 void AllowSignalHandling()
736 allowed_syscalls.insert(__NR_rt_sigaction);
737 allowed_syscalls.insert(__NR_rt_sigprocmask);
738 allowed_syscalls.insert(__NR_rt_sigreturn);
739 allowed_syscalls.insert(__NR_sigaltstack);
744 allowed_syscalls.insert(__NR_clock_nanosleep);
745 allowed_syscalls.insert(__NR_nanosleep);
750 allowed_syscalls.insert(__NR_umask);
757 std::vector<sock_filter> BuildFilter(SyscallSandboxAction default_action)
759 std::vector<sock_filter> bpf_policy;
761 bpf_policy.push_back(BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(
struct seccomp_data, arch)));
763 bpf_policy.push_back(BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, AUDIT_ARCH_X86_64, 1, 0));
764 bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_KILL_PROCESS));
766 bpf_policy.push_back(BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(
struct seccomp_data, nr)));
767 for (
const uint32_t allowed_syscall : allowed_syscalls) {
769 bpf_policy.push_back(BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, allowed_syscall, 0, 1));
770 bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW));
772 switch (default_action) {
773 case SyscallSandboxAction::KILL_PROCESS:
787 bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_KILL_PROCESS));
789 case SyscallSandboxAction::INVOKE_SIGNAL_HANDLER:
797 bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRAP));
805bool SetupSyscallSandbox(
bool log_syscall_violation_before_terminating)
807 assert(!g_syscall_sandbox_enabled &&
"SetupSyscallSandbox(...) should only be called once.");
808 g_syscall_sandbox_enabled =
true;
809 g_syscall_sandbox_log_violation_before_terminating = log_syscall_violation_before_terminating;
810 if (log_syscall_violation_before_terminating) {
811 if (!SetupSyscallSandboxDebugHandler()) {
819void TestDisallowedSandboxCall()
822 std::array<gid_t, 1> groups;
823 [[maybe_unused]] int32_t ignored = getgroups(groups.size(), groups.data());
829#if defined(USE_SYSCALL_SANDBOX)
830 if (!g_syscall_sandbox_enabled) {
833 SeccompPolicyBuilder seccomp_policy_builder;
834 switch (syscall_policy) {
843 seccomp_policy_builder.AllowFileSystem();
844 seccomp_policy_builder.AllowNetwork();
847 seccomp_policy_builder.AllowFileSystem();
848 seccomp_policy_builder.AllowNetwork();
851 seccomp_policy_builder.AllowFileSystem();
854 seccomp_policy_builder.AllowFileSystem();
855 seccomp_policy_builder.AllowNetwork();
858 seccomp_policy_builder.AllowFileSystem();
861 seccomp_policy_builder.AllowFileSystem();
862 seccomp_policy_builder.AllowNetwork();
865 seccomp_policy_builder.AllowFileSystem();
866 seccomp_policy_builder.AllowNetwork();
869 seccomp_policy_builder.AllowFileSystem();
870 seccomp_policy_builder.AllowNetwork();
873 seccomp_policy_builder.AllowFileSystem();
874 seccomp_policy_builder.AllowNetwork();
877 seccomp_policy_builder.AllowFileSystem();
878 seccomp_policy_builder.AllowNetwork();
881 seccomp_policy_builder.AllowFileSystem();
884 seccomp_policy_builder.AllowFileSystem();
885 seccomp_policy_builder.AllowNetwork();
888 seccomp_policy_builder.AllowFileSystem();
893 seccomp_policy_builder.AllowFileSystem();
897 const SyscallSandboxAction default_action = g_syscall_sandbox_log_violation_before_terminating ? SyscallSandboxAction::INVOKE_SIGNAL_HANDLER : SyscallSandboxAction::KILL_PROCESS;
898 std::vector<sock_filter> filter = seccomp_policy_builder.BuildFilter(default_action);
899 const sock_fprog prog = {
900 .len =
static_cast<uint16_t
>(filter.size()),
901 .filter = filter.data(),
906 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) {
907 throw std::runtime_error(
"Syscall sandbox enforcement failed: prctl(PR_SET_NO_NEW_PRIVS)");
912 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) != 0) {
913 throw std::runtime_error(
"Syscall sandbox enforcement failed: prctl(PR_SET_SECCOMP)");
#define LogPrint(category,...)
const std::string & ThreadGetInternalName()
Get the thread's internal (in-memory) name; used e.g.
void SetSyscallSandboxPolicy(SyscallSandboxPolicy syscall_policy)
Force the current thread (and threads created from the current thread) into a restricted-service oper...
@ INITIALIZATION_DNS_SEED
@ INITIALIZATION_MAP_PORT
@ INITIALIZATION_LOAD_BLOCKS
@ VALIDATION_SCRIPT_CHECK