158d83921SDag-Erling Smørgrav /* 258d83921SDag-Erling Smørgrav * Copyright (c) 2012 Will Drewry <wad@dataspill.org> 358d83921SDag-Erling Smørgrav * 458d83921SDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 558d83921SDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 658d83921SDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 758d83921SDag-Erling Smørgrav * 858d83921SDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 958d83921SDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1058d83921SDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1158d83921SDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1258d83921SDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1358d83921SDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1458d83921SDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1558d83921SDag-Erling Smørgrav */ 1658d83921SDag-Erling Smørgrav 1758d83921SDag-Erling Smørgrav /* 1858d83921SDag-Erling Smørgrav * Uncomment the SANDBOX_SECCOMP_FILTER_DEBUG macro below to help diagnose 1958d83921SDag-Erling Smørgrav * filter breakage during development. *Do not* use this in production, 2058d83921SDag-Erling Smørgrav * as it relies on making library calls that are unsafe in signal context. 2158d83921SDag-Erling Smørgrav * 2258d83921SDag-Erling Smørgrav * Instead, live systems the auditctl(8) may be used to monitor failures. 2358d83921SDag-Erling Smørgrav * E.g. 2458d83921SDag-Erling Smørgrav * auditctl -a task,always -F uid=<privsep uid> 2558d83921SDag-Erling Smørgrav */ 2658d83921SDag-Erling Smørgrav /* #define SANDBOX_SECCOMP_FILTER_DEBUG 1 */ 2758d83921SDag-Erling Smørgrav 28a0ee8cc6SDag-Erling Smørgrav /* XXX it should be possible to do logging via the log socket safely */ 29a0ee8cc6SDag-Erling Smørgrav 3058d83921SDag-Erling Smørgrav #ifdef SANDBOX_SECCOMP_FILTER_DEBUG 3158d83921SDag-Erling Smørgrav /* Use the kernel headers in case of an older toolchain. */ 3258d83921SDag-Erling Smørgrav # include <asm/siginfo.h> 3358d83921SDag-Erling Smørgrav # define __have_siginfo_t 1 3458d83921SDag-Erling Smørgrav # define __have_sigval_t 1 3558d83921SDag-Erling Smørgrav # define __have_sigevent_t 1 3658d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 3758d83921SDag-Erling Smørgrav 3858d83921SDag-Erling Smørgrav #include "includes.h" 3958d83921SDag-Erling Smørgrav 4058d83921SDag-Erling Smørgrav #ifdef SANDBOX_SECCOMP_FILTER 4158d83921SDag-Erling Smørgrav 4258d83921SDag-Erling Smørgrav #include <sys/types.h> 4358d83921SDag-Erling Smørgrav #include <sys/resource.h> 4458d83921SDag-Erling Smørgrav #include <sys/prctl.h> 4558d83921SDag-Erling Smørgrav 46557f75e5SDag-Erling Smørgrav #include <linux/net.h> 4758d83921SDag-Erling Smørgrav #include <linux/audit.h> 4858d83921SDag-Erling Smørgrav #include <linux/filter.h> 4958d83921SDag-Erling Smørgrav #include <linux/seccomp.h> 5058d83921SDag-Erling Smørgrav #include <elf.h> 5158d83921SDag-Erling Smørgrav 5258d83921SDag-Erling Smørgrav #include <asm/unistd.h> 5358d83921SDag-Erling Smørgrav 5458d83921SDag-Erling Smørgrav #include <errno.h> 5558d83921SDag-Erling Smørgrav #include <signal.h> 5658d83921SDag-Erling Smørgrav #include <stdarg.h> 5758d83921SDag-Erling Smørgrav #include <stddef.h> /* for offsetof */ 5858d83921SDag-Erling Smørgrav #include <stdio.h> 5958d83921SDag-Erling Smørgrav #include <stdlib.h> 6058d83921SDag-Erling Smørgrav #include <string.h> 6158d83921SDag-Erling Smørgrav #include <unistd.h> 6258d83921SDag-Erling Smørgrav 6358d83921SDag-Erling Smørgrav #include "log.h" 6458d83921SDag-Erling Smørgrav #include "ssh-sandbox.h" 6558d83921SDag-Erling Smørgrav #include "xmalloc.h" 6658d83921SDag-Erling Smørgrav 6758d83921SDag-Erling Smørgrav /* Linux seccomp_filter sandbox */ 6858d83921SDag-Erling Smørgrav #define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL 6958d83921SDag-Erling Smørgrav 7058d83921SDag-Erling Smørgrav /* Use a signal handler to emit violations when debugging */ 7158d83921SDag-Erling Smørgrav #ifdef SANDBOX_SECCOMP_FILTER_DEBUG 7258d83921SDag-Erling Smørgrav # undef SECCOMP_FILTER_FAIL 7358d83921SDag-Erling Smørgrav # define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP 7458d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 7558d83921SDag-Erling Smørgrav 76*d93a896eSDag-Erling Smørgrav #if __BYTE_ORDER == __LITTLE_ENDIAN 77*d93a896eSDag-Erling Smørgrav # define ARG_LO_OFFSET 0 78*d93a896eSDag-Erling Smørgrav # define ARG_HI_OFFSET sizeof(uint32_t) 79*d93a896eSDag-Erling Smørgrav #elif __BYTE_ORDER == __BIG_ENDIAN 80*d93a896eSDag-Erling Smørgrav # define ARG_LO_OFFSET sizeof(uint32_t) 81*d93a896eSDag-Erling Smørgrav # define ARG_HI_OFFSET 0 82*d93a896eSDag-Erling Smørgrav #else 83*d93a896eSDag-Erling Smørgrav #error "Unknown endianness" 84*d93a896eSDag-Erling Smørgrav #endif 85*d93a896eSDag-Erling Smørgrav 8658d83921SDag-Erling Smørgrav /* Simple helpers to avoid manual errors (but larger BPF programs). */ 8758d83921SDag-Erling Smørgrav #define SC_DENY(_nr, _errno) \ 88*d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \ 8958d83921SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno)) 9058d83921SDag-Erling Smørgrav #define SC_ALLOW(_nr) \ 91*d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \ 9258d83921SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) 93557f75e5SDag-Erling Smørgrav #define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ 94*d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 6), \ 95*d93a896eSDag-Erling Smørgrav /* load and test first syscall argument, low word */ \ 96557f75e5SDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 97*d93a896eSDag-Erling Smørgrav offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \ 98*d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ 99*d93a896eSDag-Erling Smørgrav ((_arg_val) & 0xFFFFFFFF), 0, 3), \ 100*d93a896eSDag-Erling Smørgrav /* load and test first syscall argument, high word */ \ 101*d93a896eSDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 102*d93a896eSDag-Erling Smørgrav offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \ 103*d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ 104*d93a896eSDag-Erling Smørgrav (((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \ 105557f75e5SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ 106557f75e5SDag-Erling Smørgrav /* reload syscall number; all rules expect it in accumulator */ \ 107557f75e5SDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 108557f75e5SDag-Erling Smørgrav offsetof(struct seccomp_data, nr)) 10958d83921SDag-Erling Smørgrav 11058d83921SDag-Erling Smørgrav /* Syscall filtering set for preauth. */ 11158d83921SDag-Erling Smørgrav static const struct sock_filter preauth_insns[] = { 11258d83921SDag-Erling Smørgrav /* Ensure the syscall arch convention is as expected. */ 11358d83921SDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 11458d83921SDag-Erling Smørgrav offsetof(struct seccomp_data, arch)), 11558d83921SDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0), 11658d83921SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), 11758d83921SDag-Erling Smørgrav /* Load the syscall number for checking. */ 11858d83921SDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 11958d83921SDag-Erling Smørgrav offsetof(struct seccomp_data, nr)), 120557f75e5SDag-Erling Smørgrav 121557f75e5SDag-Erling Smørgrav /* Syscalls to non-fatally deny */ 122076ad2f8SDag-Erling Smørgrav #ifdef __NR_lstat 123*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_lstat, EACCES), 124076ad2f8SDag-Erling Smørgrav #endif 125076ad2f8SDag-Erling Smørgrav #ifdef __NR_lstat64 126*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_lstat64, EACCES), 127076ad2f8SDag-Erling Smørgrav #endif 128557f75e5SDag-Erling Smørgrav #ifdef __NR_fstat 129*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_fstat, EACCES), 130557f75e5SDag-Erling Smørgrav #endif 131557f75e5SDag-Erling Smørgrav #ifdef __NR_fstat64 132*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_fstat64, EACCES), 133557f75e5SDag-Erling Smørgrav #endif 134557f75e5SDag-Erling Smørgrav #ifdef __NR_open 135*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_open, EACCES), 136557f75e5SDag-Erling Smørgrav #endif 137557f75e5SDag-Erling Smørgrav #ifdef __NR_openat 138*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_openat, EACCES), 139557f75e5SDag-Erling Smørgrav #endif 140557f75e5SDag-Erling Smørgrav #ifdef __NR_newfstatat 141*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_newfstatat, EACCES), 142557f75e5SDag-Erling Smørgrav #endif 143557f75e5SDag-Erling Smørgrav #ifdef __NR_stat 144*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_stat, EACCES), 14558d83921SDag-Erling Smørgrav #endif 146557f75e5SDag-Erling Smørgrav #ifdef __NR_stat64 147*d93a896eSDag-Erling Smørgrav SC_DENY(__NR_stat64, EACCES), 148b83788ffSDag-Erling Smørgrav #endif 149557f75e5SDag-Erling Smørgrav 150557f75e5SDag-Erling Smørgrav /* Syscalls to permit */ 151557f75e5SDag-Erling Smørgrav #ifdef __NR_brk 152*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_brk), 15358d83921SDag-Erling Smørgrav #endif 154557f75e5SDag-Erling Smørgrav #ifdef __NR_clock_gettime 155*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_clock_gettime), 156557f75e5SDag-Erling Smørgrav #endif 157557f75e5SDag-Erling Smørgrav #ifdef __NR_close 158*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_close), 159557f75e5SDag-Erling Smørgrav #endif 160557f75e5SDag-Erling Smørgrav #ifdef __NR_exit 161*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_exit), 162557f75e5SDag-Erling Smørgrav #endif 163557f75e5SDag-Erling Smørgrav #ifdef __NR_exit_group 164*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_exit_group), 165557f75e5SDag-Erling Smørgrav #endif 166557f75e5SDag-Erling Smørgrav #ifdef __NR_getpgid 167*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_getpgid), 168557f75e5SDag-Erling Smørgrav #endif 169557f75e5SDag-Erling Smørgrav #ifdef __NR_getpid 170*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_getpid), 171557f75e5SDag-Erling Smørgrav #endif 172acc1a9efSDag-Erling Smørgrav #ifdef __NR_getrandom 173*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_getrandom), 174acc1a9efSDag-Erling Smørgrav #endif 175557f75e5SDag-Erling Smørgrav #ifdef __NR_gettimeofday 176*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_gettimeofday), 177557f75e5SDag-Erling Smørgrav #endif 178557f75e5SDag-Erling Smørgrav #ifdef __NR_madvise 179*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_madvise), 18058d83921SDag-Erling Smørgrav #endif 18158d83921SDag-Erling Smørgrav #ifdef __NR_mmap 182*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_mmap), 18358d83921SDag-Erling Smørgrav #endif 184557f75e5SDag-Erling Smørgrav #ifdef __NR_mmap2 185*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_mmap2), 186a0ee8cc6SDag-Erling Smørgrav #endif 187557f75e5SDag-Erling Smørgrav #ifdef __NR_mremap 188*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_mremap), 189557f75e5SDag-Erling Smørgrav #endif 190557f75e5SDag-Erling Smørgrav #ifdef __NR_munmap 191*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_munmap), 192557f75e5SDag-Erling Smørgrav #endif 193557f75e5SDag-Erling Smørgrav #ifdef __NR__newselect 194*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR__newselect), 195557f75e5SDag-Erling Smørgrav #endif 196557f75e5SDag-Erling Smørgrav #ifdef __NR_poll 197*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_poll), 198557f75e5SDag-Erling Smørgrav #endif 199557f75e5SDag-Erling Smørgrav #ifdef __NR_pselect6 200*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_pselect6), 201557f75e5SDag-Erling Smørgrav #endif 202557f75e5SDag-Erling Smørgrav #ifdef __NR_read 203*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_read), 204557f75e5SDag-Erling Smørgrav #endif 20558d83921SDag-Erling Smørgrav #ifdef __NR_rt_sigprocmask 206*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_rt_sigprocmask), 207557f75e5SDag-Erling Smørgrav #endif 208557f75e5SDag-Erling Smørgrav #ifdef __NR_select 209*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_select), 210557f75e5SDag-Erling Smørgrav #endif 211557f75e5SDag-Erling Smørgrav #ifdef __NR_shutdown 212*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_shutdown), 213557f75e5SDag-Erling Smørgrav #endif 214557f75e5SDag-Erling Smørgrav #ifdef __NR_sigprocmask 215*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_sigprocmask), 21658d83921SDag-Erling Smørgrav #endif 217557f75e5SDag-Erling Smørgrav #ifdef __NR_time 218*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_time), 219557f75e5SDag-Erling Smørgrav #endif 220557f75e5SDag-Erling Smørgrav #ifdef __NR_write 221*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_write), 222557f75e5SDag-Erling Smørgrav #endif 223557f75e5SDag-Erling Smørgrav #ifdef __NR_socketcall 224*d93a896eSDag-Erling Smørgrav SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN), 225*d93a896eSDag-Erling Smørgrav #endif 226*d93a896eSDag-Erling Smørgrav #if defined(__NR_ioctl) && defined(__s390__) 227*d93a896eSDag-Erling Smørgrav /* Allow ioctls for ICA crypto card on s390 */ 228*d93a896eSDag-Erling Smørgrav SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK), 229*d93a896eSDag-Erling Smørgrav SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO), 230*d93a896eSDag-Erling Smørgrav SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), 231*d93a896eSDag-Erling Smørgrav #endif 232*d93a896eSDag-Erling Smørgrav #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) 233*d93a896eSDag-Erling Smørgrav /* 234*d93a896eSDag-Erling Smørgrav * On Linux x32, the clock_gettime VDSO falls back to the 235*d93a896eSDag-Erling Smørgrav * x86-64 syscall under some circumstances, e.g. 236*d93a896eSDag-Erling Smørgrav * https://bugs.debian.org/849923 237*d93a896eSDag-Erling Smørgrav */ 238*d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT); 239557f75e5SDag-Erling Smørgrav #endif 240557f75e5SDag-Erling Smørgrav 241557f75e5SDag-Erling Smørgrav /* Default deny */ 24258d83921SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), 24358d83921SDag-Erling Smørgrav }; 24458d83921SDag-Erling Smørgrav 24558d83921SDag-Erling Smørgrav static const struct sock_fprog preauth_program = { 24658d83921SDag-Erling Smørgrav .len = (unsigned short)(sizeof(preauth_insns)/sizeof(preauth_insns[0])), 24758d83921SDag-Erling Smørgrav .filter = (struct sock_filter *)preauth_insns, 24858d83921SDag-Erling Smørgrav }; 24958d83921SDag-Erling Smørgrav 25058d83921SDag-Erling Smørgrav struct ssh_sandbox { 25158d83921SDag-Erling Smørgrav pid_t child_pid; 25258d83921SDag-Erling Smørgrav }; 25358d83921SDag-Erling Smørgrav 25458d83921SDag-Erling Smørgrav struct ssh_sandbox * 255f7167e0eSDag-Erling Smørgrav ssh_sandbox_init(struct monitor *monitor) 25658d83921SDag-Erling Smørgrav { 25758d83921SDag-Erling Smørgrav struct ssh_sandbox *box; 25858d83921SDag-Erling Smørgrav 25958d83921SDag-Erling Smørgrav /* 26058d83921SDag-Erling Smørgrav * Strictly, we don't need to maintain any state here but we need 26158d83921SDag-Erling Smørgrav * to return non-NULL to satisfy the API. 26258d83921SDag-Erling Smørgrav */ 26358d83921SDag-Erling Smørgrav debug3("%s: preparing seccomp filter sandbox", __func__); 26458d83921SDag-Erling Smørgrav box = xcalloc(1, sizeof(*box)); 26558d83921SDag-Erling Smørgrav box->child_pid = 0; 26658d83921SDag-Erling Smørgrav 26758d83921SDag-Erling Smørgrav return box; 26858d83921SDag-Erling Smørgrav } 26958d83921SDag-Erling Smørgrav 27058d83921SDag-Erling Smørgrav #ifdef SANDBOX_SECCOMP_FILTER_DEBUG 27158d83921SDag-Erling Smørgrav extern struct monitor *pmonitor; 27258d83921SDag-Erling Smørgrav void mm_log_handler(LogLevel level, const char *msg, void *ctx); 27358d83921SDag-Erling Smørgrav 27458d83921SDag-Erling Smørgrav static void 27558d83921SDag-Erling Smørgrav ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context) 27658d83921SDag-Erling Smørgrav { 27758d83921SDag-Erling Smørgrav char msg[256]; 27858d83921SDag-Erling Smørgrav 27958d83921SDag-Erling Smørgrav snprintf(msg, sizeof(msg), 28058d83921SDag-Erling Smørgrav "%s: unexpected system call (arch:0x%x,syscall:%d @ %p)", 28158d83921SDag-Erling Smørgrav __func__, info->si_arch, info->si_syscall, info->si_call_addr); 28258d83921SDag-Erling Smørgrav mm_log_handler(SYSLOG_LEVEL_FATAL, msg, pmonitor); 28358d83921SDag-Erling Smørgrav _exit(1); 28458d83921SDag-Erling Smørgrav } 28558d83921SDag-Erling Smørgrav 28658d83921SDag-Erling Smørgrav static void 28758d83921SDag-Erling Smørgrav ssh_sandbox_child_debugging(void) 28858d83921SDag-Erling Smørgrav { 28958d83921SDag-Erling Smørgrav struct sigaction act; 29058d83921SDag-Erling Smørgrav sigset_t mask; 29158d83921SDag-Erling Smørgrav 29258d83921SDag-Erling Smørgrav debug3("%s: installing SIGSYS handler", __func__); 29358d83921SDag-Erling Smørgrav memset(&act, 0, sizeof(act)); 29458d83921SDag-Erling Smørgrav sigemptyset(&mask); 29558d83921SDag-Erling Smørgrav sigaddset(&mask, SIGSYS); 29658d83921SDag-Erling Smørgrav 29758d83921SDag-Erling Smørgrav act.sa_sigaction = &ssh_sandbox_violation; 29858d83921SDag-Erling Smørgrav act.sa_flags = SA_SIGINFO; 29958d83921SDag-Erling Smørgrav if (sigaction(SIGSYS, &act, NULL) == -1) 30058d83921SDag-Erling Smørgrav fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); 30158d83921SDag-Erling Smørgrav if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) 30258d83921SDag-Erling Smørgrav fatal("%s: sigprocmask(SIGSYS): %s", 30358d83921SDag-Erling Smørgrav __func__, strerror(errno)); 30458d83921SDag-Erling Smørgrav } 30558d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 30658d83921SDag-Erling Smørgrav 30758d83921SDag-Erling Smørgrav void 30858d83921SDag-Erling Smørgrav ssh_sandbox_child(struct ssh_sandbox *box) 30958d83921SDag-Erling Smørgrav { 31058d83921SDag-Erling Smørgrav struct rlimit rl_zero; 31158d83921SDag-Erling Smørgrav int nnp_failed = 0; 31258d83921SDag-Erling Smørgrav 31358d83921SDag-Erling Smørgrav /* Set rlimits for completeness if possible. */ 31458d83921SDag-Erling Smørgrav rl_zero.rlim_cur = rl_zero.rlim_max = 0; 31558d83921SDag-Erling Smørgrav if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) 31658d83921SDag-Erling Smørgrav fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", 31758d83921SDag-Erling Smørgrav __func__, strerror(errno)); 31858d83921SDag-Erling Smørgrav if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) 31958d83921SDag-Erling Smørgrav fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", 32058d83921SDag-Erling Smørgrav __func__, strerror(errno)); 32158d83921SDag-Erling Smørgrav if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) 32258d83921SDag-Erling Smørgrav fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", 32358d83921SDag-Erling Smørgrav __func__, strerror(errno)); 32458d83921SDag-Erling Smørgrav 32558d83921SDag-Erling Smørgrav #ifdef SANDBOX_SECCOMP_FILTER_DEBUG 32658d83921SDag-Erling Smørgrav ssh_sandbox_child_debugging(); 32758d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 32858d83921SDag-Erling Smørgrav 32958d83921SDag-Erling Smørgrav debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); 33058d83921SDag-Erling Smørgrav if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) { 33158d83921SDag-Erling Smørgrav debug("%s: prctl(PR_SET_NO_NEW_PRIVS): %s", 33258d83921SDag-Erling Smørgrav __func__, strerror(errno)); 33358d83921SDag-Erling Smørgrav nnp_failed = 1; 33458d83921SDag-Erling Smørgrav } 33558d83921SDag-Erling Smørgrav debug3("%s: attaching seccomp filter program", __func__); 33658d83921SDag-Erling Smørgrav if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1) 33758d83921SDag-Erling Smørgrav debug("%s: prctl(PR_SET_SECCOMP): %s", 33858d83921SDag-Erling Smørgrav __func__, strerror(errno)); 33958d83921SDag-Erling Smørgrav else if (nnp_failed) 34058d83921SDag-Erling Smørgrav fatal("%s: SECCOMP_MODE_FILTER activated but " 34158d83921SDag-Erling Smørgrav "PR_SET_NO_NEW_PRIVS failed", __func__); 34258d83921SDag-Erling Smørgrav } 34358d83921SDag-Erling Smørgrav 34458d83921SDag-Erling Smørgrav void 34558d83921SDag-Erling Smørgrav ssh_sandbox_parent_finish(struct ssh_sandbox *box) 34658d83921SDag-Erling Smørgrav { 34758d83921SDag-Erling Smørgrav free(box); 34858d83921SDag-Erling Smørgrav debug3("%s: finished", __func__); 34958d83921SDag-Erling Smørgrav } 35058d83921SDag-Erling Smørgrav 35158d83921SDag-Erling Smørgrav void 35258d83921SDag-Erling Smørgrav ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) 35358d83921SDag-Erling Smørgrav { 35458d83921SDag-Erling Smørgrav box->child_pid = child_pid; 35558d83921SDag-Erling Smørgrav } 35658d83921SDag-Erling Smørgrav 35758d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER */ 358