Branch data Line data Source code
# 1 : : // Copyright (c) 2020-2021 The Bitcoin Core developers
# 2 : : // Distributed under the MIT software license, see the accompanying
# 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
# 4 : :
# 5 : : #if defined(HAVE_CONFIG_H)
# 6 : : #include <config/bitcoin-config.h>
# 7 : : #endif // defined(HAVE_CONFIG_H)
# 8 : :
# 9 : : #include <util/syscall_sandbox.h>
# 10 : :
# 11 : : #if defined(USE_SYSCALL_SANDBOX)
# 12 : : #include <array>
# 13 : : #include <cassert>
# 14 : : #include <cstdint>
# 15 : : #include <exception>
# 16 : : #include <map>
# 17 : : #include <new>
# 18 : : #include <set>
# 19 : : #include <string>
# 20 : : #include <vector>
# 21 : :
# 22 : : #include <logging.h>
# 23 : : #include <tinyformat.h>
# 24 : : #include <util/threadnames.h>
# 25 : :
# 26 : : #include <linux/audit.h>
# 27 : : #include <linux/filter.h>
# 28 : : #include <linux/seccomp.h>
# 29 : : #include <linux/unistd.h>
# 30 : : #include <signal.h>
# 31 : : #include <sys/prctl.h>
# 32 : : #include <sys/types.h>
# 33 : : #include <unistd.h>
# 34 : :
# 35 : : namespace {
# 36 : : bool g_syscall_sandbox_enabled{false};
# 37 : : bool g_syscall_sandbox_log_violation_before_terminating{false};
# 38 : :
# 39 : : #if !defined(__x86_64__)
# 40 : : #error Syscall sandbox is an experimental feature currently available only under Linux x86-64.
# 41 : : #endif // defined(__x86_64__)
# 42 : :
# 43 : : #ifndef SECCOMP_RET_KILL_PROCESS
# 44 : : #define SECCOMP_RET_KILL_PROCESS 0x80000000U
# 45 : : #endif
# 46 : :
# 47 : : // Define system call numbers for x86_64 that are referenced in the system call profile
# 48 : : // but not provided by the kernel headers used in the GUIX build.
# 49 : : // Usually, they can be found via "grep name /usr/include/x86_64-linux-gnu/asm/unistd_64.h"
# 50 : :
# 51 : : #ifndef __NR_clone3
# 52 : : #define __NR_clone3 435
# 53 : : #endif
# 54 : :
# 55 : : #ifndef __NR_statx
# 56 : : #define __NR_statx 332
# 57 : : #endif
# 58 : :
# 59 : : #ifndef __NR_getrandom
# 60 : : #define __NR_getrandom 318
# 61 : : #endif
# 62 : :
# 63 : : #ifndef __NR_membarrier
# 64 : : #define __NR_membarrier 324
# 65 : : #endif
# 66 : :
# 67 : : #ifndef __NR_copy_file_range
# 68 : : #define __NR_copy_file_range 326
# 69 : : #endif
# 70 : :
# 71 : : #ifndef __NR_rseq
# 72 : : #define __NR_rseq 334
# 73 : : #endif
# 74 : :
# 75 : : // This list of syscalls in LINUX_SYSCALLS is only used to map syscall numbers to syscall names in
# 76 : : // order to be able to print user friendly error messages which include the syscall name in addition
# 77 : : // to the syscall number.
# 78 : : //
# 79 : : // Example output in case of a syscall violation where the syscall is present in LINUX_SYSCALLS:
# 80 : : //
# 81 : : // ```
# 82 : : // 2021-06-09T12:34:56Z ERROR: The syscall "execve" (syscall number 59) is not allowed by the syscall sandbox in thread "msghand". Please report.
# 83 : : // ```
# 84 : : //
# 85 : : // Example output in case of a syscall violation where the syscall is not present in LINUX_SYSCALLS:
# 86 : : //
# 87 : : // ```
# 88 : : // 2021-06-09T12:34:56Z ERROR: The syscall "*unknown*" (syscall number 314) is not allowed by the syscall sandbox in thread "msghand". Please report.
# 89 : : // ``
# 90 : : //
# 91 : : // LINUX_SYSCALLS contains two types of syscalls:
# 92 : : // 1.) Syscalls that are present under all architectures or relevant Linux kernel versions for which
# 93 : : // we support the syscall sandbox feature (currently only Linux x86-64). Examples include read,
# 94 : : // write, open, close, etc.
# 95 : : // 2.) Syscalls that are present under a subset of architectures or relevant Linux kernel versions
# 96 : : // for which we support the syscall sandbox feature. This type of syscalls should be added to
# 97 : : // LINUX_SYSCALLS conditional on availability like in the following example:
# 98 : : // ...
# 99 : : // #if defined(__NR_arch_dependent_syscall)
# 100 : : // {__NR_arch_dependent_syscall, "arch_dependent_syscall"},
# 101 : : // #endif // defined(__NR_arch_dependent_syscall)
# 102 : : // ...
# 103 : : const std::map<uint32_t, std::string> LINUX_SYSCALLS{
# 104 : : {__NR_accept, "accept"},
# 105 : : {__NR_accept4, "accept4"},
# 106 : : {__NR_access, "access"},
# 107 : : {__NR_acct, "acct"},
# 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"},
# 113 : : {__NR_bind, "bind"},
# 114 : : {__NR_bpf, "bpf"},
# 115 : : {__NR_brk, "brk"},
# 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"},
# 135 : : {__NR_dup, "dup"},
# 136 : : {__NR_dup2, "dup2"},
# 137 : : {__NR_dup3, "dup3"},
# 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"},
# 149 : : {__NR_exit, "exit"},
# 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"},
# 167 : : {__NR_fork, "fork"},
# 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"},
# 220 : : {__NR_iopl, "iopl"},
# 221 : : {__NR_ioprio_get, "ioprio_get"},
# 222 : : {__NR_ioprio_set, "ioprio_set"},
# 223 : : {__NR_kcmp, "kcmp"},
# 224 : : {__NR_kexec_file_load, "kexec_file_load"},
# 225 : : {__NR_kexec_load, "kexec_load"},
# 226 : : {__NR_keyctl, "keyctl"},
# 227 : : {__NR_kill, "kill"},
# 228 : : {__NR_lchown, "lchown"},
# 229 : : {__NR_lgetxattr, "lgetxattr"},
# 230 : : {__NR_link, "link"},
# 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"},
# 253 : : {__NR_mmap, "mmap"},
# 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"},
# 277 : : {__NR_open, "open"},
# 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"},
# 283 : : {__NR_pipe, "pipe"},
# 284 : : {__NR_pipe2, "pipe2"},
# 285 : : {__NR_pivot_root, "pivot_root"},
# 286 : : #ifdef __NR_pkey_alloc
# 287 : : {__NR_pkey_alloc, "pkey_alloc"},
# 288 : : #endif
# 289 : : #ifdef __NR_pkey_free
# 290 : : {__NR_pkey_free, "pkey_free"},
# 291 : : #endif
# 292 : : #ifdef __NR_pkey_mprotect
# 293 : : {__NR_pkey_mprotect, "pkey_mprotect"},
# 294 : : #endif
# 295 : : {__NR_poll, "poll"},
# 296 : : {__NR_ppoll, "ppoll"},
# 297 : : {__NR_prctl, "prctl"},
# 298 : : {__NR_pread64, "pread64"},
# 299 : : {__NR_preadv, "preadv"},
# 300 : : #ifdef __NR_preadv2
# 301 : : {__NR_preadv2, "preadv2"},
# 302 : : #endif
# 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"},
# 311 : : #ifdef __NR_pwritev2
# 312 : : {__NR_pwritev2, "pwritev2"},
# 313 : : #endif
# 314 : : {__NR__sysctl, "_sysctl"},
# 315 : : {__NR_query_module, "query_module"},
# 316 : : {__NR_quotactl, "quotactl"},
# 317 : : {__NR_read, "read"},
# 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"},
# 334 : : {__NR_rseq, "rseq"},
# 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"},
# 401 : : {__NR_stat, "stat"},
# 402 : : {__NR_statfs, "statfs"},
# 403 : : {__NR_statx, "statx"},
# 404 : : {__NR_swapoff, "swapoff"},
# 405 : : {__NR_swapon, "swapon"},
# 406 : : {__NR_symlink, "symlink"},
# 407 : : {__NR_symlinkat, "symlinkat"},
# 408 : : {__NR_sync, "sync"},
# 409 : : {__NR_sync_file_range, "sync_file_range"},
# 410 : : {__NR_syncfs, "syncfs"},
# 411 : : {__NR_sysfs, "sysfs"},
# 412 : : {__NR_sysinfo, "sysinfo"},
# 413 : : {__NR_syslog, "syslog"},
# 414 : : {__NR_tee, "tee"},
# 415 : : {__NR_tgkill, "tgkill"},
# 416 : : {__NR_time, "time"},
# 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"},
# 449 : : };
# 450 : :
# 451 : : std::string GetLinuxSyscallName(uint32_t syscall_number)
# 452 : : {
# 453 : : const auto element = LINUX_SYSCALLS.find(syscall_number);
# 454 : : if (element != LINUX_SYSCALLS.end()) {
# 455 : : return element->second;
# 456 : : }
# 457 : : return "*unknown*";
# 458 : : }
# 459 : :
# 460 : : // See Linux kernel developer Kees Cook's seccomp guide at <https://outflux.net/teach-seccomp/> for
# 461 : : // an accessible introduction to using seccomp.
# 462 : : //
# 463 : : // This function largely follows <https://outflux.net/teach-seccomp/step-3/syscall-reporter.c> and
# 464 : : // <https://outflux.net/teach-seccomp/step-3/seccomp-bpf.h>.
# 465 : : //
# 466 : : // Seccomp BPF resources:
# 467 : : // * Seccomp BPF documentation: <https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html>
# 468 : : // * seccomp(2) manual page: <https://www.kernel.org/doc/man-pages/online/pages/man2/seccomp.2.html>
# 469 : : // * Seccomp BPF demo code samples: <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/seccomp>
# 470 : : void SyscallSandboxDebugSignalHandler(int, siginfo_t* signal_info, void* void_signal_context)
# 471 : : {
# 472 : : // The si_code field inside the siginfo_t argument that is passed to a SA_SIGINFO signal handler
# 473 : : // is a value indicating why the signal was sent.
# 474 : : //
# 475 : : // The following value can be placed in si_code for a SIGSYS signal:
# 476 : : // * SYS_SECCOMP (since Linux 3.5): Triggered by a seccomp(2) filter rule.
# 477 : : constexpr int32_t SYS_SECCOMP_SI_CODE{1};
# 478 : : assert(signal_info->si_code == SYS_SECCOMP_SI_CODE);
# 479 : :
# 480 : : // The ucontext_t structure contains signal context information that was saved on the user-space
# 481 : : // stack by the kernel.
# 482 : : const ucontext_t* signal_context = static_cast<ucontext_t*>(void_signal_context);
# 483 : : assert(signal_context != nullptr);
# 484 : :
# 485 : : std::set_new_handler(std::terminate);
# 486 : : // Portability note: REG_RAX is Linux x86_64 specific.
# 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);
# 489 : : const std::string thread_name = !util::ThreadGetInternalName().empty() ? util::ThreadGetInternalName() : "*unnamed*";
# 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);
# 491 : : tfm::format(std::cerr, "%s\n", error_message);
# 492 : : LogPrintf("%s\n", error_message);
# 493 : : std::terminate();
# 494 : : }
# 495 : :
# 496 : : // This function largely follows install_syscall_reporter from Kees Cook's seccomp guide:
# 497 : : // <https://outflux.net/teach-seccomp/step-3/syscall-reporter.c>
# 498 : : bool SetupSyscallSandboxDebugHandler()
# 499 : : {
# 500 : : struct sigaction action = {};
# 501 : : sigset_t mask;
# 502 : : sigemptyset(&mask);
# 503 : : sigaddset(&mask, SIGSYS);
# 504 : : action.sa_sigaction = &SyscallSandboxDebugSignalHandler;
# 505 : : action.sa_flags = SA_SIGINFO;
# 506 : : if (sigaction(SIGSYS, &action, nullptr) < 0) {
# 507 : : return false;
# 508 : : }
# 509 : : if (sigprocmask(SIG_UNBLOCK, &mask, nullptr)) {
# 510 : : return false;
# 511 : : }
# 512 : : return true;
# 513 : : }
# 514 : :
# 515 : : enum class SyscallSandboxAction {
# 516 : : KILL_PROCESS,
# 517 : : INVOKE_SIGNAL_HANDLER,
# 518 : : };
# 519 : :
# 520 : : class SeccompPolicyBuilder
# 521 : : {
# 522 : : std::set<uint32_t> allowed_syscalls;
# 523 : :
# 524 : : public:
# 525 : : SeccompPolicyBuilder()
# 526 : : {
# 527 : : // Allowed by default.
# 528 : : AllowAddressSpaceAccess();
# 529 : : AllowEpoll();
# 530 : : AllowEventFd();
# 531 : : AllowFutex();
# 532 : : AllowGeneralIo();
# 533 : : AllowGetRandom();
# 534 : : AllowGetSimpleId();
# 535 : : AllowGetTime();
# 536 : : AllowGlobalProcessEnvironment();
# 537 : : AllowGlobalSystemStatus();
# 538 : : AllowKernelInternalApi();
# 539 : : AllowNetworkSocketInformation();
# 540 : : AllowOperationOnExistingFileDescriptor();
# 541 : : AllowPipe();
# 542 : : AllowPrctl();
# 543 : : AllowProcessStartOrDeath();
# 544 : : AllowScheduling();
# 545 : : AllowSignalHandling();
# 546 : : AllowSleep();
# 547 : : AllowUmask();
# 548 : : }
# 549 : :
# 550 : : void AllowAddressSpaceAccess()
# 551 : : {
# 552 : : allowed_syscalls.insert(__NR_brk); // change data segment size
# 553 : : allowed_syscalls.insert(__NR_madvise); // give advice about use of memory
# 554 : : allowed_syscalls.insert(__NR_membarrier); // issue memory barriers on a set of threads
# 555 : : allowed_syscalls.insert(__NR_mincore); // check if virtual memory is in RAM
# 556 : : allowed_syscalls.insert(__NR_mlock); // lock memory
# 557 : : allowed_syscalls.insert(__NR_mmap); // map files or devices into memory
# 558 : : allowed_syscalls.insert(__NR_mprotect); // set protection on a region of memory
# 559 : : allowed_syscalls.insert(__NR_mremap); // remap a file in memory
# 560 : : allowed_syscalls.insert(__NR_munlock); // unlock memory
# 561 : : allowed_syscalls.insert(__NR_munmap); // unmap files or devices into memory
# 562 : : }
# 563 : :
# 564 : : void AllowEpoll()
# 565 : : {
# 566 : : allowed_syscalls.insert(__NR_epoll_create1); // open an epoll file descriptor
# 567 : : allowed_syscalls.insert(__NR_epoll_ctl); // control interface for an epoll file descriptor
# 568 : : allowed_syscalls.insert(__NR_epoll_pwait); // wait for an I/O event on an epoll file descriptor
# 569 : : allowed_syscalls.insert(__NR_epoll_wait); // wait for an I/O event on an epoll file descriptor
# 570 : : }
# 571 : :
# 572 : : void AllowEventFd()
# 573 : : {
# 574 : : allowed_syscalls.insert(__NR_eventfd2); // create a file descriptor for event notification
# 575 : : }
# 576 : :
# 577 : : void AllowFileSystem()
# 578 : : {
# 579 : : allowed_syscalls.insert(__NR_access); // check user's permissions for a file
# 580 : : allowed_syscalls.insert(__NR_chdir); // change working directory
# 581 : : allowed_syscalls.insert(__NR_chmod); // change permissions of a file
# 582 : : allowed_syscalls.insert(__NR_copy_file_range); // copy a range of data from one file to another
# 583 : : allowed_syscalls.insert(__NR_fallocate); // manipulate file space
# 584 : : allowed_syscalls.insert(__NR_fchmod); // change permissions of a file
# 585 : : allowed_syscalls.insert(__NR_fchown); // change ownership of a file
# 586 : : allowed_syscalls.insert(__NR_fdatasync); // synchronize a file's in-core state with storage device
# 587 : : allowed_syscalls.insert(__NR_flock); // apply or remove an advisory lock on an open file
# 588 : : allowed_syscalls.insert(__NR_fstat); // get file status
# 589 : : allowed_syscalls.insert(__NR_fstatfs); // get file system status
# 590 : : allowed_syscalls.insert(__NR_fsync); // synchronize a file's in-core state with storage device
# 591 : : allowed_syscalls.insert(__NR_ftruncate); // truncate a file to a specified length
# 592 : : allowed_syscalls.insert(__NR_getcwd); // get current working directory
# 593 : : allowed_syscalls.insert(__NR_getdents); // get directory entries
# 594 : : allowed_syscalls.insert(__NR_getdents64); // get directory entries
# 595 : : allowed_syscalls.insert(__NR_lstat); // get file status
# 596 : : allowed_syscalls.insert(__NR_mkdir); // create a directory
# 597 : : allowed_syscalls.insert(__NR_newfstatat); // get file status
# 598 : : allowed_syscalls.insert(__NR_open); // open and possibly create a file
# 599 : : allowed_syscalls.insert(__NR_openat); // open and possibly create a file
# 600 : : allowed_syscalls.insert(__NR_readlink); // read value of a symbolic link
# 601 : : allowed_syscalls.insert(__NR_rename); // change the name or location of a file
# 602 : : allowed_syscalls.insert(__NR_rmdir); // delete a directory
# 603 : : allowed_syscalls.insert(__NR_sendfile); // transfer data between file descriptors
# 604 : : allowed_syscalls.insert(__NR_stat); // get file status
# 605 : : allowed_syscalls.insert(__NR_statfs); // get filesystem statistics
# 606 : : allowed_syscalls.insert(__NR_statx); // get file status (extended)
# 607 : : allowed_syscalls.insert(__NR_unlink); // delete a name and possibly the file it refers to
# 608 : : allowed_syscalls.insert(__NR_unlinkat); // delete relative to a directory file descriptor
# 609 : : }
# 610 : :
# 611 : : void AllowFutex()
# 612 : : {
# 613 : : allowed_syscalls.insert(__NR_futex); // fast user-space locking
# 614 : : allowed_syscalls.insert(__NR_set_robust_list); // set list of robust futexes
# 615 : : }
# 616 : :
# 617 : : void AllowGeneralIo()
# 618 : : {
# 619 : : allowed_syscalls.insert(__NR_ioctl); // control device
# 620 : : allowed_syscalls.insert(__NR_lseek); // reposition read/write file offset
# 621 : : allowed_syscalls.insert(__NR_poll); // wait for some event on a file descriptor
# 622 : : allowed_syscalls.insert(__NR_ppoll); // wait for some event on a file descriptor
# 623 : : allowed_syscalls.insert(__NR_pread64); // read from a file descriptor at a given offset
# 624 : : allowed_syscalls.insert(__NR_pwrite64); // write to a file descriptor at a given offset
# 625 : : allowed_syscalls.insert(__NR_read); // read from a file descriptor
# 626 : : allowed_syscalls.insert(__NR_readv); // read data into multiple buffers
# 627 : : allowed_syscalls.insert(__NR_recvfrom); // receive a message from a socket
# 628 : : allowed_syscalls.insert(__NR_recvmsg); // receive a message from a socket
# 629 : : allowed_syscalls.insert(__NR_select); // synchronous I/O multiplexing
# 630 : : allowed_syscalls.insert(__NR_sendmmsg); // send multiple messages on a socket
# 631 : : allowed_syscalls.insert(__NR_sendmsg); // send a message on a socket
# 632 : : allowed_syscalls.insert(__NR_sendto); // send a message on a socket
# 633 : : allowed_syscalls.insert(__NR_write); // write to a file descriptor
# 634 : : allowed_syscalls.insert(__NR_writev); // write data into multiple buffers
# 635 : : }
# 636 : :
# 637 : : void AllowGetRandom()
# 638 : : {
# 639 : : allowed_syscalls.insert(__NR_getrandom); // obtain a series of random bytes
# 640 : : }
# 641 : :
# 642 : : void AllowGetSimpleId()
# 643 : : {
# 644 : : allowed_syscalls.insert(__NR_getegid); // get group identity
# 645 : : allowed_syscalls.insert(__NR_geteuid); // get user identity
# 646 : : allowed_syscalls.insert(__NR_getgid); // get group identity
# 647 : : allowed_syscalls.insert(__NR_getpgid); // get process group
# 648 : : allowed_syscalls.insert(__NR_getpid); // get process identification
# 649 : : allowed_syscalls.insert(__NR_getppid); // get process identification
# 650 : : allowed_syscalls.insert(__NR_getresgid); // get real, effective and saved group IDs
# 651 : : allowed_syscalls.insert(__NR_getresuid); // get real, effective and saved user IDs
# 652 : : allowed_syscalls.insert(__NR_getsid); // get session ID
# 653 : : allowed_syscalls.insert(__NR_gettid); // get thread identification
# 654 : : allowed_syscalls.insert(__NR_getuid); // get user identity
# 655 : : }
# 656 : :
# 657 : : void AllowGetTime()
# 658 : : {
# 659 : : allowed_syscalls.insert(__NR_clock_getres); // find the resolution (precision) of the specified clock
# 660 : : allowed_syscalls.insert(__NR_clock_gettime); // retrieve the time of the specified clock
# 661 : : allowed_syscalls.insert(__NR_gettimeofday); // get timeval
# 662 : : }
# 663 : :
# 664 : : void AllowGlobalProcessEnvironment()
# 665 : : {
# 666 : : allowed_syscalls.insert(__NR_getrlimit); // get resource limits
# 667 : : allowed_syscalls.insert(__NR_getrusage); // get resource usage
# 668 : : allowed_syscalls.insert(__NR_prlimit64); // get/set resource limits
# 669 : : }
# 670 : :
# 671 : : void AllowGlobalSystemStatus()
# 672 : : {
# 673 : : allowed_syscalls.insert(__NR_sysinfo); // return system information
# 674 : : allowed_syscalls.insert(__NR_uname); // get name and information about current kernel
# 675 : : }
# 676 : :
# 677 : : void AllowKernelInternalApi()
# 678 : : {
# 679 : : allowed_syscalls.insert(__NR_restart_syscall); // restart a system call after interruption by a stop signal
# 680 : : }
# 681 : :
# 682 : : void AllowNetwork()
# 683 : : {
# 684 : : allowed_syscalls.insert(__NR_accept); // accept a connection on a socket
# 685 : : allowed_syscalls.insert(__NR_accept4); // accept a connection on a socket
# 686 : : allowed_syscalls.insert(__NR_bind); // bind a name to a socket
# 687 : : allowed_syscalls.insert(__NR_connect); // initiate a connection on a socket
# 688 : : allowed_syscalls.insert(__NR_listen); // listen for connections on a socket
# 689 : : allowed_syscalls.insert(__NR_setsockopt); // set options on sockets
# 690 : : allowed_syscalls.insert(__NR_socket); // create an endpoint for communication
# 691 : : allowed_syscalls.insert(__NR_socketpair); // create a pair of connected sockets
# 692 : : }
# 693 : :
# 694 : : void AllowNetworkSocketInformation()
# 695 : : {
# 696 : : allowed_syscalls.insert(__NR_getpeername); // get name of connected peer socket
# 697 : : allowed_syscalls.insert(__NR_getsockname); // get socket name
# 698 : : allowed_syscalls.insert(__NR_getsockopt); // get options on sockets
# 699 : : }
# 700 : :
# 701 : : void AllowOperationOnExistingFileDescriptor()
# 702 : : {
# 703 : : allowed_syscalls.insert(__NR_close); // close a file descriptor
# 704 : : allowed_syscalls.insert(__NR_dup); // duplicate a file descriptor
# 705 : : allowed_syscalls.insert(__NR_dup2); // duplicate a file descriptor
# 706 : : allowed_syscalls.insert(__NR_fcntl); // manipulate file descriptor
# 707 : : allowed_syscalls.insert(__NR_shutdown); // shut down part of a full-duplex connection
# 708 : : }
# 709 : :
# 710 : : void AllowPipe()
# 711 : : {
# 712 : : allowed_syscalls.insert(__NR_pipe); // create pipe
# 713 : : allowed_syscalls.insert(__NR_pipe2); // create pipe
# 714 : : }
# 715 : :
# 716 : : void AllowPrctl()
# 717 : : {
# 718 : : allowed_syscalls.insert(__NR_arch_prctl); // set architecture-specific thread state
# 719 : : allowed_syscalls.insert(__NR_prctl); // operations on a process
# 720 : : }
# 721 : :
# 722 : : void AllowProcessStartOrDeath()
# 723 : : {
# 724 : : allowed_syscalls.insert(__NR_clone); // create a child process
# 725 : : allowed_syscalls.insert(__NR_clone3); // create a child process
# 726 : : allowed_syscalls.insert(__NR_exit); // terminate the calling process
# 727 : : allowed_syscalls.insert(__NR_exit_group); // exit all threads in a process
# 728 : : allowed_syscalls.insert(__NR_fork); // create a child process
# 729 : : allowed_syscalls.insert(__NR_tgkill); // send a signal to a thread
# 730 : : allowed_syscalls.insert(__NR_wait4); // wait for process to change state, BSD style
# 731 : : allowed_syscalls.insert(__NR_rseq); // register restartable sequence for thread
# 732 : : }
# 733 : :
# 734 : : void AllowScheduling()
# 735 : : {
# 736 : : allowed_syscalls.insert(__NR_sched_getaffinity); // set a thread's CPU affinity mask
# 737 : : allowed_syscalls.insert(__NR_sched_getparam); // get scheduling parameters
# 738 : : allowed_syscalls.insert(__NR_sched_getscheduler); // get scheduling policy/parameters
# 739 : : allowed_syscalls.insert(__NR_sched_setscheduler); // set scheduling policy/parameters
# 740 : : allowed_syscalls.insert(__NR_sched_yield); // yield the processor
# 741 : : }
# 742 : :
# 743 : : void AllowSignalHandling()
# 744 : : {
# 745 : : allowed_syscalls.insert(__NR_rt_sigaction); // examine and change a signal action
# 746 : : allowed_syscalls.insert(__NR_rt_sigprocmask); // examine and change blocked signals
# 747 : : allowed_syscalls.insert(__NR_rt_sigreturn); // return from signal handler and cleanup stack frame
# 748 : : allowed_syscalls.insert(__NR_sigaltstack); // set and/or get signal stack context
# 749 : : }
# 750 : :
# 751 : : void AllowSleep()
# 752 : : {
# 753 : : allowed_syscalls.insert(__NR_clock_nanosleep); // high-resolution sleep with specifiable clock
# 754 : : allowed_syscalls.insert(__NR_nanosleep); // high-resolution sleep
# 755 : : }
# 756 : :
# 757 : : void AllowUmask()
# 758 : : {
# 759 : : allowed_syscalls.insert(__NR_umask); // set file mode creation mask
# 760 : : }
# 761 : :
# 762 : : // See Linux kernel developer Kees Cook's seccomp guide at <https://outflux.net/teach-seccomp/>
# 763 : : // for an accessible introduction to using seccomp.
# 764 : : //
# 765 : : // This function largely follows <https://outflux.net/teach-seccomp/step-3/seccomp-bpf.h>.
# 766 : : std::vector<sock_filter> BuildFilter(SyscallSandboxAction default_action)
# 767 : : {
# 768 : : std::vector<sock_filter> bpf_policy;
# 769 : : // See VALIDATE_ARCHITECTURE in seccomp-bpf.h referenced above.
# 770 : : bpf_policy.push_back(BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct seccomp_data, arch)));
# 771 : : // Portability note: AUDIT_ARCH_X86_64 is Linux x86_64 specific.
# 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));
# 774 : : // See EXAMINE_SYSCALL in seccomp-bpf.h referenced above.
# 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) {
# 777 : : // See ALLOW_SYSCALL in seccomp-bpf.h referenced above.
# 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));
# 780 : : }
# 781 : : switch (default_action) {
# 782 : : case SyscallSandboxAction::KILL_PROCESS:
# 783 : : // Disallow syscall and kill the process.
# 784 : : //
# 785 : : // See KILL_PROCESS in seccomp-bpf.h referenced above.
# 786 : : //
# 787 : : // Note that we're using SECCOMP_RET_KILL_PROCESS (kill the process) instead
# 788 : : // of SECCOMP_RET_KILL_THREAD (kill the thread). The SECCOMP_RET_KILL_PROCESS
# 789 : : // action was introduced in Linux 4.14.
# 790 : : //
# 791 : : // SECCOMP_RET_KILL_PROCESS: Results in the entire process exiting immediately without
# 792 : : // executing the system call.
# 793 : : //
# 794 : : // SECCOMP_RET_KILL_PROCESS documentation:
# 795 : : // <https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html>
# 796 : : bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_KILL_PROCESS));
# 797 : : break;
# 798 : : case SyscallSandboxAction::INVOKE_SIGNAL_HANDLER:
# 799 : : // Disallow syscall and force a SIGSYS to trigger syscall debug reporter.
# 800 : : //
# 801 : : // SECCOMP_RET_TRAP: Results in the kernel sending a SIGSYS signal to the triggering
# 802 : : // task without executing the system call.
# 803 : : //
# 804 : : // SECCOMP_RET_TRAP documentation:
# 805 : : // <https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html>
# 806 : : bpf_policy.push_back(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRAP));
# 807 : : break;
# 808 : : }
# 809 : : return bpf_policy;
# 810 : : }
# 811 : : };
# 812 : : } // namespace
# 813 : :
# 814 : : bool SetupSyscallSandbox(bool log_syscall_violation_before_terminating)
# 815 : : {
# 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()) {
# 821 : : return false;
# 822 : : }
# 823 : : }
# 824 : : return true;
# 825 : : }
# 826 : :
# 827 : : void TestDisallowedSandboxCall()
# 828 : : {
# 829 : : // The getgroups syscall is assumed NOT to be allowed by the syscall sandbox policy.
# 830 : : std::array<gid_t, 1> groups;
# 831 : : [[maybe_unused]] int32_t ignored = getgroups(groups.size(), groups.data());
# 832 : : }
# 833 : : #endif // defined(USE_SYSCALL_SANDBOX)
# 834 : :
# 835 : : void SetSyscallSandboxPolicy(SyscallSandboxPolicy syscall_policy)
# 836 : 14711 : {
# 837 : : #if defined(USE_SYSCALL_SANDBOX)
# 838 : : if (!g_syscall_sandbox_enabled) {
# 839 : : return;
# 840 : : }
# 841 : : SeccompPolicyBuilder seccomp_policy_builder;
# 842 : : switch (syscall_policy) {
# 843 : : case SyscallSandboxPolicy::INITIALIZATION: // Thread: main thread (state: init)
# 844 : : // SyscallSandboxPolicy::INITIALIZATION is the first policy loaded.
# 845 : : //
# 846 : : // Subsequently loaded policies can reduce the abilities further, but
# 847 : : // abilities can never be regained.
# 848 : : //
# 849 : : // SyscallSandboxPolicy::INITIALIZATION must thus be a superset of all
# 850 : : // other policies.
# 851 : : seccomp_policy_builder.AllowFileSystem();
# 852 : : seccomp_policy_builder.AllowNetwork();
# 853 : : break;
# 854 : : case SyscallSandboxPolicy::INITIALIZATION_DNS_SEED: // Thread: dnsseed
# 855 : : seccomp_policy_builder.AllowFileSystem();
# 856 : : seccomp_policy_builder.AllowNetwork();
# 857 : : break;
# 858 : : case SyscallSandboxPolicy::INITIALIZATION_LOAD_BLOCKS: // Thread: loadblk
# 859 : : seccomp_policy_builder.AllowFileSystem();
# 860 : : break;
# 861 : : case SyscallSandboxPolicy::INITIALIZATION_MAP_PORT: // Thread: mapport
# 862 : : seccomp_policy_builder.AllowFileSystem();
# 863 : : seccomp_policy_builder.AllowNetwork();
# 864 : : break;
# 865 : : case SyscallSandboxPolicy::MESSAGE_HANDLER: // Thread: msghand
# 866 : : seccomp_policy_builder.AllowFileSystem();
# 867 : : break;
# 868 : : case SyscallSandboxPolicy::NET: // Thread: net
# 869 : : seccomp_policy_builder.AllowFileSystem();
# 870 : : seccomp_policy_builder.AllowNetwork();
# 871 : : break;
# 872 : : case SyscallSandboxPolicy::NET_ADD_CONNECTION: // Thread: addcon
# 873 : : seccomp_policy_builder.AllowFileSystem();
# 874 : : seccomp_policy_builder.AllowNetwork();
# 875 : : break;
# 876 : : case SyscallSandboxPolicy::NET_HTTP_SERVER: // Thread: http
# 877 : : seccomp_policy_builder.AllowFileSystem();
# 878 : : seccomp_policy_builder.AllowNetwork();
# 879 : : break;
# 880 : : case SyscallSandboxPolicy::NET_HTTP_SERVER_WORKER: // Thread: httpworker.<N>
# 881 : : seccomp_policy_builder.AllowFileSystem();
# 882 : : seccomp_policy_builder.AllowNetwork();
# 883 : : break;
# 884 : : case SyscallSandboxPolicy::NET_OPEN_CONNECTION: // Thread: opencon
# 885 : : seccomp_policy_builder.AllowFileSystem();
# 886 : : seccomp_policy_builder.AllowNetwork();
# 887 : : break;
# 888 : : case SyscallSandboxPolicy::SCHEDULER: // Thread: scheduler
# 889 : : seccomp_policy_builder.AllowFileSystem();
# 890 : : break;
# 891 : : case SyscallSandboxPolicy::TOR_CONTROL: // Thread: torcontrol
# 892 : : seccomp_policy_builder.AllowFileSystem();
# 893 : : seccomp_policy_builder.AllowNetwork();
# 894 : : break;
# 895 : : case SyscallSandboxPolicy::TX_INDEX: // Thread: txindex
# 896 : : seccomp_policy_builder.AllowFileSystem();
# 897 : : break;
# 898 : : case SyscallSandboxPolicy::VALIDATION_SCRIPT_CHECK: // Thread: scriptch.<N>
# 899 : : break;
# 900 : : case SyscallSandboxPolicy::SHUTOFF: // Thread: main thread (state: shutoff)
# 901 : : seccomp_policy_builder.AllowFileSystem();
# 902 : : break;
# 903 : : }
# 904 : :
# 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(),
# 910 : : };
# 911 : : // Do not allow abilities to be regained after being dropped.
# 912 : : //
# 913 : : // PR_SET_NO_NEW_PRIVS documentation: <https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html>
# 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)");
# 916 : : }
# 917 : : // Install seccomp-bpf syscall filter.
# 918 : : //
# 919 : : // PR_SET_SECCOMP documentation: <https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html>
# 920 : : if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) != 0) {
# 921 : : throw std::runtime_error("Syscall sandbox enforcement failed: prctl(PR_SET_SECCOMP)");
# 922 : : }
# 923 : :
# 924 : : const std::string thread_name = !util::ThreadGetInternalName().empty() ? util::ThreadGetInternalName() : "*unnamed*";
# 925 : : LogPrint(BCLog::UTIL, "Syscall filter installed for thread \"%s\"\n", thread_name);
# 926 : : #endif // defined(USE_SYSCALL_SANDBOX)
# 927 : 14711 : }
|