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>
31 #include <sys/prctl.h>
32 #include <sys/types.h>
36 bool g_syscall_sandbox_enabled{
false};
37 bool 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
56 #define __NR_statx 332
59 #ifndef __NR_getrandom
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
103 const std::map<uint32_t, std::string> LINUX_SYSCALLS{
104 {__NR_accept,
"accept"},
105 {__NR_accept4,
"accept4"},
106 {__NR_access,
"access"},
108 {__NR_add_key,
"add_key"},
109 {__NR_adjtimex,
"adjtimex"},
110 {__NR_afs_syscall,
"afs_syscall"},
111 {__NR_alarm,
"alarm"},
112 {__NR_arch_prctl,
"arch_prctl"},
116 {__NR_capget,
"capget"},
117 {__NR_capset,
"capset"},
118 {__NR_chdir,
"chdir"},
119 {__NR_chmod,
"chmod"},
120 {__NR_chown,
"chown"},
121 {__NR_chroot,
"chroot"},
122 {__NR_clock_adjtime,
"clock_adjtime"},
123 {__NR_clock_getres,
"clock_getres"},
124 {__NR_clock_gettime,
"clock_gettime"},
125 {__NR_clock_nanosleep,
"clock_nanosleep"},
126 {__NR_clock_settime,
"clock_settime"},
127 {__NR_clone,
"clone"},
128 {__NR_clone3,
"clone3"},
129 {__NR_close,
"close"},
130 {__NR_connect,
"connect"},
131 {__NR_copy_file_range,
"copy_file_range"},
132 {__NR_creat,
"creat"},
133 {__NR_create_module,
"create_module"},
134 {__NR_delete_module,
"delete_module"},
138 {__NR_epoll_create,
"epoll_create"},
139 {__NR_epoll_create1,
"epoll_create1"},
140 {__NR_epoll_ctl,
"epoll_ctl"},
141 {__NR_epoll_ctl_old,
"epoll_ctl_old"},
142 {__NR_epoll_pwait,
"epoll_pwait"},
143 {__NR_epoll_wait,
"epoll_wait"},
144 {__NR_epoll_wait_old,
"epoll_wait_old"},
145 {__NR_eventfd,
"eventfd"},
146 {__NR_eventfd2,
"eventfd2"},
147 {__NR_execve,
"execve"},
148 {__NR_execveat,
"execveat"},
150 {__NR_exit_group,
"exit_group"},
151 {__NR_faccessat,
"faccessat"},
152 {__NR_fadvise64,
"fadvise64"},
153 {__NR_fallocate,
"fallocate"},
154 {__NR_fanotify_init,
"fanotify_init"},
155 {__NR_fanotify_mark,
"fanotify_mark"},
156 {__NR_fchdir,
"fchdir"},
157 {__NR_fchmod,
"fchmod"},
158 {__NR_fchmodat,
"fchmodat"},
159 {__NR_fchown,
"fchown"},
160 {__NR_fchownat,
"fchownat"},
161 {__NR_fcntl,
"fcntl"},
162 {__NR_fdatasync,
"fdatasync"},
163 {__NR_fgetxattr,
"fgetxattr"},
164 {__NR_finit_module,
"finit_module"},
165 {__NR_flistxattr,
"flistxattr"},
166 {__NR_flock,
"flock"},
168 {__NR_fremovexattr,
"fremovexattr"},
169 {__NR_fsetxattr,
"fsetxattr"},
170 {__NR_fstat,
"fstat"},
171 {__NR_fstatfs,
"fstatfs"},
172 {__NR_fsync,
"fsync"},
173 {__NR_ftruncate,
"ftruncate"},
174 {__NR_futex,
"futex"},
175 {__NR_futimesat,
"futimesat"},
176 {__NR_get_kernel_syms,
"get_kernel_syms"},
177 {__NR_get_mempolicy,
"get_mempolicy"},
178 {__NR_get_robust_list,
"get_robust_list"},
179 {__NR_get_thread_area,
"get_thread_area"},
180 {__NR_getcpu,
"getcpu"},
181 {__NR_getcwd,
"getcwd"},
182 {__NR_getdents,
"getdents"},
183 {__NR_getdents64,
"getdents64"},
184 {__NR_getegid,
"getegid"},
185 {__NR_geteuid,
"geteuid"},
186 {__NR_getgid,
"getgid"},
187 {__NR_getgroups,
"getgroups"},
188 {__NR_getitimer,
"getitimer"},
189 {__NR_getpeername,
"getpeername"},
190 {__NR_getpgid,
"getpgid"},
191 {__NR_getpgrp,
"getpgrp"},
192 {__NR_getpid,
"getpid"},
193 {__NR_getpmsg,
"getpmsg"},
194 {__NR_getppid,
"getppid"},
195 {__NR_getpriority,
"getpriority"},
196 {__NR_getrandom,
"getrandom"},
197 {__NR_getresgid,
"getresgid"},
198 {__NR_getresuid,
"getresuid"},
199 {__NR_getrlimit,
"getrlimit"},
200 {__NR_getrusage,
"getrusage"},
201 {__NR_getsid,
"getsid"},
202 {__NR_getsockname,
"getsockname"},
203 {__NR_getsockopt,
"getsockopt"},
204 {__NR_gettid,
"gettid"},
205 {__NR_gettimeofday,
"gettimeofday"},
206 {__NR_getuid,
"getuid"},
207 {__NR_getxattr,
"getxattr"},
208 {__NR_init_module,
"init_module"},
209 {__NR_inotify_add_watch,
"inotify_add_watch"},
210 {__NR_inotify_init,
"inotify_init"},
211 {__NR_inotify_init1,
"inotify_init1"},
212 {__NR_inotify_rm_watch,
"inotify_rm_watch"},
213 {__NR_io_cancel,
"io_cancel"},
214 {__NR_io_destroy,
"io_destroy"},
215 {__NR_io_getevents,
"io_getevents"},
216 {__NR_io_setup,
"io_setup"},
217 {__NR_io_submit,
"io_submit"},
218 {__NR_ioctl,
"ioctl"},
219 {__NR_ioperm,
"ioperm"},
221 {__NR_ioprio_get,
"ioprio_get"},
222 {__NR_ioprio_set,
"ioprio_set"},
224 {__NR_kexec_file_load,
"kexec_file_load"},
225 {__NR_kexec_load,
"kexec_load"},
226 {__NR_keyctl,
"keyctl"},
228 {__NR_lchown,
"lchown"},
229 {__NR_lgetxattr,
"lgetxattr"},
231 {__NR_linkat,
"linkat"},
232 {__NR_listen,
"listen"},
233 {__NR_listxattr,
"listxattr"},
234 {__NR_llistxattr,
"llistxattr"},
235 {__NR_lookup_dcookie,
"lookup_dcookie"},
236 {__NR_lremovexattr,
"lremovexattr"},
237 {__NR_lseek,
"lseek"},
238 {__NR_lsetxattr,
"lsetxattr"},
239 {__NR_lstat,
"lstat"},
240 {__NR_madvise,
"madvise"},
241 {__NR_mbind,
"mbind"},
242 {__NR_membarrier,
"membarrier"},
243 {__NR_memfd_create,
"memfd_create"},
244 {__NR_migrate_pages,
"migrate_pages"},
245 {__NR_mincore,
"mincore"},
246 {__NR_mkdir,
"mkdir"},
247 {__NR_mkdirat,
"mkdirat"},
248 {__NR_mknod,
"mknod"},
249 {__NR_mknodat,
"mknodat"},
250 {__NR_mlock,
"mlock"},
251 {__NR_mlock2,
"mlock2"},
252 {__NR_mlockall,
"mlockall"},
254 {__NR_modify_ldt,
"modify_ldt"},
255 {__NR_mount,
"mount"},
256 {__NR_move_pages,
"move_pages"},
257 {__NR_mprotect,
"mprotect"},
258 {__NR_mq_getsetattr,
"mq_getsetattr"},
259 {__NR_mq_notify,
"mq_notify"},
260 {__NR_mq_open,
"mq_open"},
261 {__NR_mq_timedreceive,
"mq_timedreceive"},
262 {__NR_mq_timedsend,
"mq_timedsend"},
263 {__NR_mq_unlink,
"mq_unlink"},
264 {__NR_mremap,
"mremap"},
265 {__NR_msgctl,
"msgctl"},
266 {__NR_msgget,
"msgget"},
267 {__NR_msgrcv,
"msgrcv"},
268 {__NR_msgsnd,
"msgsnd"},
269 {__NR_msync,
"msync"},
270 {__NR_munlock,
"munlock"},
271 {__NR_munlockall,
"munlockall"},
272 {__NR_munmap,
"munmap"},
273 {__NR_name_to_handle_at,
"name_to_handle_at"},
274 {__NR_nanosleep,
"nanosleep"},
275 {__NR_newfstatat,
"newfstatat"},
276 {__NR_nfsservctl,
"nfsservctl"},
278 {__NR_open_by_handle_at,
"open_by_handle_at"},
279 {__NR_openat,
"openat"},
280 {__NR_pause,
"pause"},
281 {__NR_perf_event_open,
"perf_event_open"},
282 {__NR_personality,
"personality"},
284 {__NR_pipe2,
"pipe2"},
285 {__NR_pivot_root,
"pivot_root"},
286 #ifdef __NR_pkey_alloc
287 {__NR_pkey_alloc,
"pkey_alloc"},
289 #ifdef __NR_pkey_free
290 {__NR_pkey_free,
"pkey_free"},
292 #ifdef __NR_pkey_mprotect
293 {__NR_pkey_mprotect,
"pkey_mprotect"},
296 {__NR_ppoll,
"ppoll"},
297 {__NR_prctl,
"prctl"},
298 {__NR_pread64,
"pread64"},
299 {__NR_preadv,
"preadv"},
301 {__NR_preadv2,
"preadv2"},
303 {__NR_prlimit64,
"prlimit64"},
304 {__NR_process_vm_readv,
"process_vm_readv"},
305 {__NR_process_vm_writev,
"process_vm_writev"},
306 {__NR_pselect6,
"pselect6"},
307 {__NR_ptrace,
"ptrace"},
308 {__NR_putpmsg,
"putpmsg"},
309 {__NR_pwrite64,
"pwrite64"},
310 {__NR_pwritev,
"pwritev"},
312 {__NR_pwritev2,
"pwritev2"},
314 {__NR__sysctl,
"_sysctl"},
315 {__NR_query_module,
"query_module"},
316 {__NR_quotactl,
"quotactl"},
318 {__NR_readahead,
"readahead"},
319 {__NR_readlink,
"readlink"},
320 {__NR_readlinkat,
"readlinkat"},
321 {__NR_readv,
"readv"},
322 {__NR_reboot,
"reboot"},
323 {__NR_recvfrom,
"recvfrom"},
324 {__NR_recvmmsg,
"recvmmsg"},
325 {__NR_recvmsg,
"recvmsg"},
326 {__NR_remap_file_pages,
"remap_file_pages"},
327 {__NR_removexattr,
"removexattr"},
328 {__NR_rename,
"rename"},
329 {__NR_renameat,
"renameat"},
330 {__NR_renameat2,
"renameat2"},
331 {__NR_request_key,
"request_key"},
332 {__NR_restart_syscall,
"restart_syscall"},
333 {__NR_rmdir,
"rmdir"},
335 {__NR_rt_sigaction,
"rt_sigaction"},
336 {__NR_rt_sigpending,
"rt_sigpending"},
337 {__NR_rt_sigprocmask,
"rt_sigprocmask"},
338 {__NR_rt_sigqueueinfo,
"rt_sigqueueinfo"},
339 {__NR_rt_sigreturn,
"rt_sigreturn"},
340 {__NR_rt_sigsuspend,
"rt_sigsuspend"},
341 {__NR_rt_sigtimedwait,
"rt_sigtimedwait"},
342 {__NR_rt_tgsigqueueinfo,
"rt_tgsigqueueinfo"},
343 {__NR_sched_get_priority_max,
"sched_get_priority_max"},
344 {__NR_sched_get_priority_min,
"sched_get_priority_min"},
345 {__NR_sched_getaffinity,
"sched_getaffinity"},
346 {__NR_sched_getattr,
"sched_getattr"},
347 {__NR_sched_getparam,
"sched_getparam"},
348 {__NR_sched_getscheduler,
"sched_getscheduler"},
349 {__NR_sched_rr_get_interval,
"sched_rr_get_interval"},
350 {__NR_sched_setaffinity,
"sched_setaffinity"},
351 {__NR_sched_setattr,
"sched_setattr"},
352 {__NR_sched_setparam,
"sched_setparam"},
353 {__NR_sched_setscheduler,
"sched_setscheduler"},
354 {__NR_sched_yield,
"sched_yield"},
355 {__NR_seccomp,
"seccomp"},
356 {__NR_security,
"security"},
357 {__NR_select,
"select"},
358 {__NR_semctl,
"semctl"},
359 {__NR_semget,
"semget"},
360 {__NR_semop,
"semop"},
361 {__NR_semtimedop,
"semtimedop"},
362 {__NR_sendfile,
"sendfile"},
363 {__NR_sendmmsg,
"sendmmsg"},
364 {__NR_sendmsg,
"sendmsg"},
365 {__NR_sendto,
"sendto"},
366 {__NR_set_mempolicy,
"set_mempolicy"},
367 {__NR_set_robust_list,
"set_robust_list"},
368 {__NR_set_thread_area,
"set_thread_area"},
369 {__NR_set_tid_address,
"set_tid_address"},
370 {__NR_setdomainname,
"setdomainname"},
371 {__NR_setfsgid,
"setfsgid"},
372 {__NR_setfsuid,
"setfsuid"},
373 {__NR_setgid,
"setgid"},
374 {__NR_setgroups,
"setgroups"},
375 {__NR_sethostname,
"sethostname"},
376 {__NR_setitimer,
"setitimer"},
377 {__NR_setns,
"setns"},
378 {__NR_setpgid,
"setpgid"},
379 {__NR_setpriority,
"setpriority"},
380 {__NR_setregid,
"setregid"},
381 {__NR_setresgid,
"setresgid"},
382 {__NR_setresuid,
"setresuid"},
383 {__NR_setreuid,
"setreuid"},
384 {__NR_setrlimit,
"setrlimit"},
385 {__NR_setsid,
"setsid"},
386 {__NR_setsockopt,
"setsockopt"},
387 {__NR_settimeofday,
"settimeofday"},
388 {__NR_setuid,
"setuid"},
389 {__NR_setxattr,
"setxattr"},
390 {__NR_shmat,
"shmat"},
391 {__NR_shmctl,
"shmctl"},
392 {__NR_shmdt,
"shmdt"},
393 {__NR_shmget,
"shmget"},
394 {__NR_shutdown,
"shutdown"},
395 {__NR_sigaltstack,
"sigaltstack"},
396 {__NR_signalfd,
"signalfd"},
397 {__NR_signalfd4,
"signalfd4"},
398 {__NR_socket,
"socket"},
399 {__NR_socketpair,
"socketpair"},
400 {__NR_splice,
"splice"},
402 {__NR_statfs,
"statfs"},
403 {__NR_statx,
"statx"},
404 {__NR_swapoff,
"swapoff"},
405 {__NR_swapon,
"swapon"},
406 {__NR_symlink,
"symlink"},
407 {__NR_symlinkat,
"symlinkat"},
409 {__NR_sync_file_range,
"sync_file_range"},
410 {__NR_syncfs,
"syncfs"},
411 {__NR_sysfs,
"sysfs"},
412 {__NR_sysinfo,
"sysinfo"},
413 {__NR_syslog,
"syslog"},
415 {__NR_tgkill,
"tgkill"},
417 {__NR_timer_create,
"timer_create"},
418 {__NR_timer_delete,
"timer_delete"},
419 {__NR_timer_getoverrun,
"timer_getoverrun"},
420 {__NR_timer_gettime,
"timer_gettime"},
421 {__NR_timer_settime,
"timer_settime"},
422 {__NR_timerfd_create,
"timerfd_create"},
423 {__NR_timerfd_gettime,
"timerfd_gettime"},
424 {__NR_timerfd_settime,
"timerfd_settime"},
425 {__NR_times,
"times"},
426 {__NR_tkill,
"tkill"},
427 {__NR_truncate,
"truncate"},
428 {__NR_tuxcall,
"tuxcall"},
429 {__NR_umask,
"umask"},
430 {__NR_umount2,
"umount2"},
431 {__NR_uname,
"uname"},
432 {__NR_unlink,
"unlink"},
433 {__NR_unlinkat,
"unlinkat"},
434 {__NR_unshare,
"unshare"},
435 {__NR_uselib,
"uselib"},
436 {__NR_userfaultfd,
"userfaultfd"},
437 {__NR_ustat,
"ustat"},
438 {__NR_utime,
"utime"},
439 {__NR_utimensat,
"utimensat"},
440 {__NR_utimes,
"utimes"},
441 {__NR_vfork,
"vfork"},
442 {__NR_vhangup,
"vhangup"},
443 {__NR_vmsplice,
"vmsplice"},
444 {__NR_vserver,
"vserver"},
445 {__NR_wait4,
"wait4"},
446 {__NR_waitid,
"waitid"},
447 {__NR_write,
"write"},
448 {__NR_writev,
"writev"},
451 std::string GetLinuxSyscallName(uint32_t syscall_number)
453 const auto element = LINUX_SYSCALLS.find(syscall_number);
454 if (element != LINUX_SYSCALLS.end()) {
455 return element->second;
470 void SyscallSandboxDebugSignalHandler(
int, siginfo_t* signal_info,
void* void_signal_context)
477 constexpr int32_t SYS_SECCOMP_SI_CODE{1};
478 assert(signal_info->si_code == SYS_SECCOMP_SI_CODE);
482 const ucontext_t* signal_context =
static_cast<ucontext_t*
>(void_signal_context);
483 assert(signal_context !=
nullptr);
485 std::set_new_handler(std::terminate);
487 const uint32_t syscall_number =
static_cast<uint32_t
>(signal_context->uc_mcontext.gregs[REG_RAX]);
488 const std::string syscall_name = GetLinuxSyscallName(syscall_number);
490 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);
498 bool SetupSyscallSandboxDebugHandler()
500 struct sigaction action = {};
503 sigaddset(&mask, SIGSYS);
504 action.sa_sigaction = &SyscallSandboxDebugSignalHandler;
505 action.sa_flags = SA_SIGINFO;
506 if (sigaction(SIGSYS, &action,
nullptr) < 0) {
509 if (sigprocmask(SIG_UNBLOCK, &mask,
nullptr)) {
515 enum class SyscallSandboxAction {
517 INVOKE_SIGNAL_HANDLER,
520 class SeccompPolicyBuilder
522 std::set<uint32_t> allowed_syscalls;
525 SeccompPolicyBuilder()
528 AllowAddressSpaceAccess();
536 AllowGlobalProcessEnvironment();
537 AllowGlobalSystemStatus();
538 AllowKernelInternalApi();
539 AllowNetworkSocketInformation();
540 AllowOperationOnExistingFileDescriptor();
543 AllowProcessStartOrDeath();
545 AllowSignalHandling();
550 void AllowAddressSpaceAccess()
552 allowed_syscalls.insert(__NR_brk);
553 allowed_syscalls.insert(__NR_madvise);
554 allowed_syscalls.insert(__NR_membarrier);
555 allowed_syscalls.insert(__NR_mincore);
556 allowed_syscalls.insert(__NR_mlock);
557 allowed_syscalls.insert(__NR_mmap);
558 allowed_syscalls.insert(__NR_mprotect);
559 allowed_syscalls.insert(__NR_mremap);
560 allowed_syscalls.insert(__NR_munlock);
561 allowed_syscalls.insert(__NR_munmap);
566 allowed_syscalls.insert(__NR_epoll_create1);
567 allowed_syscalls.insert(__NR_epoll_ctl);
568 allowed_syscalls.insert(__NR_epoll_pwait);
569 allowed_syscalls.insert(__NR_epoll_wait);
574 allowed_syscalls.insert(__NR_eventfd2);
577 void AllowFileSystem()
579 allowed_syscalls.insert(__NR_access);
580 allowed_syscalls.insert(__NR_chdir);
581 allowed_syscalls.insert(__NR_chmod);
582 allowed_syscalls.insert(__NR_copy_file_range);
583 allowed_syscalls.insert(__NR_fallocate);
584 allowed_syscalls.insert(__NR_fchmod);
585 allowed_syscalls.insert(__NR_fchown);
586 allowed_syscalls.insert(__NR_fdatasync);
587 allowed_syscalls.insert(__NR_flock);
588 allowed_syscalls.insert(__NR_fstat);
589 allowed_syscalls.insert(__NR_fstatfs);
590 allowed_syscalls.insert(__NR_fsync);
591 allowed_syscalls.insert(__NR_ftruncate);
592 allowed_syscalls.insert(__NR_getcwd);
593 allowed_syscalls.insert(__NR_getdents);
594 allowed_syscalls.insert(__NR_getdents64);
595 allowed_syscalls.insert(__NR_lstat);
596 allowed_syscalls.insert(__NR_mkdir);
597 allowed_syscalls.insert(__NR_newfstatat);
598 allowed_syscalls.insert(__NR_open);
599 allowed_syscalls.insert(__NR_openat);
600 allowed_syscalls.insert(__NR_readlink);
601 allowed_syscalls.insert(__NR_rename);
602 allowed_syscalls.insert(__NR_rmdir);
603 allowed_syscalls.insert(__NR_sendfile);
604 allowed_syscalls.insert(__NR_stat);
605 allowed_syscalls.insert(__NR_statfs);
606 allowed_syscalls.insert(__NR_statx);
607 allowed_syscalls.insert(__NR_unlink);
608 allowed_syscalls.insert(__NR_unlinkat);
613 allowed_syscalls.insert(__NR_futex);
614 allowed_syscalls.insert(__NR_set_robust_list);
617 void AllowGeneralIo()
619 allowed_syscalls.insert(__NR_ioctl);
620 allowed_syscalls.insert(__NR_lseek);
621 allowed_syscalls.insert(__NR_poll);
622 allowed_syscalls.insert(__NR_ppoll);
623 allowed_syscalls.insert(__NR_pread64);
624 allowed_syscalls.insert(__NR_pwrite64);
625 allowed_syscalls.insert(__NR_read);
626 allowed_syscalls.insert(__NR_readv);
627 allowed_syscalls.insert(__NR_recvfrom);
628 allowed_syscalls.insert(__NR_recvmsg);
629 allowed_syscalls.insert(__NR_select);
630 allowed_syscalls.insert(__NR_sendmmsg);
631 allowed_syscalls.insert(__NR_sendmsg);
632 allowed_syscalls.insert(__NR_sendto);
633 allowed_syscalls.insert(__NR_write);
634 allowed_syscalls.insert(__NR_writev);
637 void AllowGetRandom()
639 allowed_syscalls.insert(__NR_getrandom);
642 void AllowGetSimpleId()
644 allowed_syscalls.insert(__NR_getegid);
645 allowed_syscalls.insert(__NR_geteuid);
646 allowed_syscalls.insert(__NR_getgid);
647 allowed_syscalls.insert(__NR_getpgid);
648 allowed_syscalls.insert(__NR_getpid);
649 allowed_syscalls.insert(__NR_getppid);
650 allowed_syscalls.insert(__NR_getresgid);
651 allowed_syscalls.insert(__NR_getresuid);
652 allowed_syscalls.insert(__NR_getsid);
653 allowed_syscalls.insert(__NR_gettid);
654 allowed_syscalls.insert(__NR_getuid);
659 allowed_syscalls.insert(__NR_clock_getres);
660 allowed_syscalls.insert(__NR_clock_gettime);
661 allowed_syscalls.insert(__NR_gettimeofday);
664 void AllowGlobalProcessEnvironment()
666 allowed_syscalls.insert(__NR_getrlimit);
667 allowed_syscalls.insert(__NR_getrusage);
668 allowed_syscalls.insert(__NR_prlimit64);
671 void AllowGlobalSystemStatus()
673 allowed_syscalls.insert(__NR_sysinfo);
674 allowed_syscalls.insert(__NR_uname);
677 void AllowKernelInternalApi()
679 allowed_syscalls.insert(__NR_restart_syscall);
684 allowed_syscalls.insert(__NR_accept);
685 allowed_syscalls.insert(__NR_accept4);
686 allowed_syscalls.insert(__NR_bind);
687 allowed_syscalls.insert(__NR_connect);
688 allowed_syscalls.insert(__NR_listen);
689 allowed_syscalls.insert(__NR_setsockopt);
690 allowed_syscalls.insert(__NR_socket);
691 allowed_syscalls.insert(__NR_socketpair);
694 void AllowNetworkSocketInformation()
696 allowed_syscalls.insert(__NR_getpeername);
697 allowed_syscalls.insert(__NR_getsockname);
698 allowed_syscalls.insert(__NR_getsockopt);
701 void AllowOperationOnExistingFileDescriptor()
703 allowed_syscalls.insert(__NR_close);
704 allowed_syscalls.insert(__NR_dup);
705 allowed_syscalls.insert(__NR_dup2);
706 allowed_syscalls.insert(__NR_fcntl);
707 allowed_syscalls.insert(__NR_shutdown);
712 allowed_syscalls.insert(__NR_pipe);
713 allowed_syscalls.insert(__NR_pipe2);
718 allowed_syscalls.insert(__NR_arch_prctl);
719 allowed_syscalls.insert(__NR_prctl);
722 void AllowProcessStartOrDeath()
724 allowed_syscalls.insert(__NR_clone);
725 allowed_syscalls.insert(__NR_clone3);
726 allowed_syscalls.insert(__NR_exit);
727 allowed_syscalls.insert(__NR_exit_group);
728 allowed_syscalls.insert(__NR_fork);
729 allowed_syscalls.insert(__NR_tgkill);
730 allowed_syscalls.insert(__NR_wait4);
731 allowed_syscalls.insert(__NR_rseq);
734 void AllowScheduling()
736 allowed_syscalls.insert(__NR_sched_getaffinity);
737 allowed_syscalls.insert(__NR_sched_getparam);
738 allowed_syscalls.insert(__NR_sched_getscheduler);
739 allowed_syscalls.insert(__NR_sched_setscheduler);
740 allowed_syscalls.insert(__NR_sched_yield);
743 void AllowSignalHandling()
745 allowed_syscalls.insert(__NR_rt_sigaction);
746 allowed_syscalls.insert(__NR_rt_sigprocmask);
747 allowed_syscalls.insert(__NR_rt_sigreturn);
748 allowed_syscalls.insert(__NR_sigaltstack);
753 allowed_syscalls.insert(__NR_clock_nanosleep);
754 allowed_syscalls.insert(__NR_nanosleep);
759 allowed_syscalls.insert(__NR_umask);
766 std::vector<sock_filter> BuildFilter(SyscallSandboxAction default_action)
768 std::vector<sock_filter> bpf_policy;
770 bpf_policy.push_back(BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(
struct seccomp_data, arch)));
772 bpf_policy.push_back(BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, AUDIT_ARCH_X86_64, 1, 0));
773 bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_KILL_PROCESS));
775 bpf_policy.push_back(BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(
struct seccomp_data, nr)));
776 for (
const uint32_t allowed_syscall : allowed_syscalls) {
778 bpf_policy.push_back(BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, allowed_syscall, 0, 1));
779 bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW));
781 switch (default_action) {
782 case SyscallSandboxAction::KILL_PROCESS:
796 bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_KILL_PROCESS));
798 case SyscallSandboxAction::INVOKE_SIGNAL_HANDLER:
806 bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRAP));
814 bool SetupSyscallSandbox(
bool log_syscall_violation_before_terminating)
816 assert(!g_syscall_sandbox_enabled &&
"SetupSyscallSandbox(...) should only be called once.");
817 g_syscall_sandbox_enabled =
true;
818 g_syscall_sandbox_log_violation_before_terminating = log_syscall_violation_before_terminating;
819 if (log_syscall_violation_before_terminating) {
820 if (!SetupSyscallSandboxDebugHandler()) {
827 void TestDisallowedSandboxCall()
830 std::array<gid_t, 1> groups;
831 [[maybe_unused]] int32_t ignored = getgroups(groups.size(), groups.data());
837 #if defined(USE_SYSCALL_SANDBOX)
838 if (!g_syscall_sandbox_enabled) {
841 SeccompPolicyBuilder seccomp_policy_builder;
842 switch (syscall_policy) {
851 seccomp_policy_builder.AllowFileSystem();
852 seccomp_policy_builder.AllowNetwork();
855 seccomp_policy_builder.AllowFileSystem();
856 seccomp_policy_builder.AllowNetwork();
859 seccomp_policy_builder.AllowFileSystem();
862 seccomp_policy_builder.AllowFileSystem();
863 seccomp_policy_builder.AllowNetwork();
866 seccomp_policy_builder.AllowFileSystem();
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();
882 seccomp_policy_builder.AllowNetwork();
885 seccomp_policy_builder.AllowFileSystem();
886 seccomp_policy_builder.AllowNetwork();
889 seccomp_policy_builder.AllowFileSystem();
892 seccomp_policy_builder.AllowFileSystem();
893 seccomp_policy_builder.AllowNetwork();
896 seccomp_policy_builder.AllowFileSystem();
901 seccomp_policy_builder.AllowFileSystem();
905 const SyscallSandboxAction default_action = g_syscall_sandbox_log_violation_before_terminating ? SyscallSandboxAction::INVOKE_SIGNAL_HANDLER : SyscallSandboxAction::KILL_PROCESS;
906 std::vector<sock_filter> filter = seccomp_policy_builder.BuildFilter(default_action);
907 const sock_fprog prog = {
908 .len =
static_cast<uint16_t
>(filter.size()),
909 .filter = filter.data(),
914 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) {
915 throw std::runtime_error(
"Syscall sandbox enforcement failed: prctl(PR_SET_NO_NEW_PRIVS)");
920 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) != 0) {
921 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