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> 534f52dfbbSDag-Erling Smørgrav #ifdef __s390__ 544f52dfbbSDag-Erling Smørgrav #include <asm/zcrypt.h> 554f52dfbbSDag-Erling Smørgrav #endif 5658d83921SDag-Erling Smørgrav 5758d83921SDag-Erling Smørgrav #include <errno.h> 5858d83921SDag-Erling Smørgrav #include <signal.h> 5958d83921SDag-Erling Smørgrav #include <stdarg.h> 6058d83921SDag-Erling Smørgrav #include <stddef.h> /* for offsetof */ 6158d83921SDag-Erling Smørgrav #include <stdio.h> 6258d83921SDag-Erling Smørgrav #include <stdlib.h> 6358d83921SDag-Erling Smørgrav #include <string.h> 6458d83921SDag-Erling Smørgrav #include <unistd.h> 6558d83921SDag-Erling Smørgrav 6658d83921SDag-Erling Smørgrav #include "log.h" 6758d83921SDag-Erling Smørgrav #include "ssh-sandbox.h" 6858d83921SDag-Erling Smørgrav #include "xmalloc.h" 6958d83921SDag-Erling Smørgrav 7058d83921SDag-Erling Smørgrav /* Linux seccomp_filter sandbox */ 7158d83921SDag-Erling Smørgrav #define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL 7258d83921SDag-Erling Smørgrav 7358d83921SDag-Erling Smørgrav /* Use a signal handler to emit violations when debugging */ 7458d83921SDag-Erling Smørgrav #ifdef SANDBOX_SECCOMP_FILTER_DEBUG 7558d83921SDag-Erling Smørgrav # undef SECCOMP_FILTER_FAIL 7658d83921SDag-Erling Smørgrav # define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP 7758d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 7858d83921SDag-Erling Smørgrav 79d93a896eSDag-Erling Smørgrav #if __BYTE_ORDER == __LITTLE_ENDIAN 80d93a896eSDag-Erling Smørgrav # define ARG_LO_OFFSET 0 81d93a896eSDag-Erling Smørgrav # define ARG_HI_OFFSET sizeof(uint32_t) 82d93a896eSDag-Erling Smørgrav #elif __BYTE_ORDER == __BIG_ENDIAN 83d93a896eSDag-Erling Smørgrav # define ARG_LO_OFFSET sizeof(uint32_t) 84d93a896eSDag-Erling Smørgrav # define ARG_HI_OFFSET 0 85d93a896eSDag-Erling Smørgrav #else 86d93a896eSDag-Erling Smørgrav #error "Unknown endianness" 87d93a896eSDag-Erling Smørgrav #endif 88d93a896eSDag-Erling Smørgrav 8958d83921SDag-Erling Smørgrav /* Simple helpers to avoid manual errors (but larger BPF programs). */ 9058d83921SDag-Erling Smørgrav #define SC_DENY(_nr, _errno) \ 91d93a896eSDag-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_ERRNO|(_errno)) 9358d83921SDag-Erling Smørgrav #define SC_ALLOW(_nr) \ 94d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \ 9558d83921SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) 96557f75e5SDag-Erling Smørgrav #define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ 97d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 6), \ 98d93a896eSDag-Erling Smørgrav /* load and test first syscall argument, low word */ \ 99557f75e5SDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 100d93a896eSDag-Erling Smørgrav offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \ 101d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ 102d93a896eSDag-Erling Smørgrav ((_arg_val) & 0xFFFFFFFF), 0, 3), \ 103d93a896eSDag-Erling Smørgrav /* load and test first syscall argument, high word */ \ 104d93a896eSDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 105d93a896eSDag-Erling Smørgrav offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \ 106d93a896eSDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ 107d93a896eSDag-Erling Smørgrav (((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \ 108557f75e5SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ 109557f75e5SDag-Erling Smørgrav /* reload syscall number; all rules expect it in accumulator */ \ 110557f75e5SDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ 111557f75e5SDag-Erling Smørgrav offsetof(struct seccomp_data, nr)) 11258d83921SDag-Erling Smørgrav 11358d83921SDag-Erling Smørgrav /* Syscall filtering set for preauth. */ 11458d83921SDag-Erling Smørgrav static const struct sock_filter preauth_insns[] = { 11558d83921SDag-Erling Smørgrav /* Ensure the syscall arch convention is as expected. */ 11658d83921SDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 11758d83921SDag-Erling Smørgrav offsetof(struct seccomp_data, arch)), 11858d83921SDag-Erling Smørgrav BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0), 11958d83921SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), 12058d83921SDag-Erling Smørgrav /* Load the syscall number for checking. */ 12158d83921SDag-Erling Smørgrav BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 12258d83921SDag-Erling Smørgrav offsetof(struct seccomp_data, nr)), 123557f75e5SDag-Erling Smørgrav 124557f75e5SDag-Erling Smørgrav /* Syscalls to non-fatally deny */ 125076ad2f8SDag-Erling Smørgrav #ifdef __NR_lstat 126d93a896eSDag-Erling Smørgrav SC_DENY(__NR_lstat, EACCES), 127076ad2f8SDag-Erling Smørgrav #endif 128076ad2f8SDag-Erling Smørgrav #ifdef __NR_lstat64 129d93a896eSDag-Erling Smørgrav SC_DENY(__NR_lstat64, EACCES), 130076ad2f8SDag-Erling Smørgrav #endif 131557f75e5SDag-Erling Smørgrav #ifdef __NR_fstat 132d93a896eSDag-Erling Smørgrav SC_DENY(__NR_fstat, EACCES), 133557f75e5SDag-Erling Smørgrav #endif 134557f75e5SDag-Erling Smørgrav #ifdef __NR_fstat64 135d93a896eSDag-Erling Smørgrav SC_DENY(__NR_fstat64, EACCES), 136557f75e5SDag-Erling Smørgrav #endif 137557f75e5SDag-Erling Smørgrav #ifdef __NR_open 138d93a896eSDag-Erling Smørgrav SC_DENY(__NR_open, EACCES), 139557f75e5SDag-Erling Smørgrav #endif 140557f75e5SDag-Erling Smørgrav #ifdef __NR_openat 141d93a896eSDag-Erling Smørgrav SC_DENY(__NR_openat, EACCES), 142557f75e5SDag-Erling Smørgrav #endif 143557f75e5SDag-Erling Smørgrav #ifdef __NR_newfstatat 144d93a896eSDag-Erling Smørgrav SC_DENY(__NR_newfstatat, EACCES), 145557f75e5SDag-Erling Smørgrav #endif 146557f75e5SDag-Erling Smørgrav #ifdef __NR_stat 147d93a896eSDag-Erling Smørgrav SC_DENY(__NR_stat, EACCES), 14858d83921SDag-Erling Smørgrav #endif 149557f75e5SDag-Erling Smørgrav #ifdef __NR_stat64 150d93a896eSDag-Erling Smørgrav SC_DENY(__NR_stat64, EACCES), 151b83788ffSDag-Erling Smørgrav #endif 152557f75e5SDag-Erling Smørgrav 153557f75e5SDag-Erling Smørgrav /* Syscalls to permit */ 154557f75e5SDag-Erling Smørgrav #ifdef __NR_brk 155d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_brk), 15658d83921SDag-Erling Smørgrav #endif 157557f75e5SDag-Erling Smørgrav #ifdef __NR_clock_gettime 158d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_clock_gettime), 159557f75e5SDag-Erling Smørgrav #endif 160557f75e5SDag-Erling Smørgrav #ifdef __NR_close 161d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_close), 162557f75e5SDag-Erling Smørgrav #endif 163557f75e5SDag-Erling Smørgrav #ifdef __NR_exit 164d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_exit), 165557f75e5SDag-Erling Smørgrav #endif 166557f75e5SDag-Erling Smørgrav #ifdef __NR_exit_group 167d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_exit_group), 168557f75e5SDag-Erling Smørgrav #endif 169*190cef3dSDag-Erling Smørgrav #ifdef __NR_geteuid 170*190cef3dSDag-Erling Smørgrav SC_ALLOW(__NR_geteuid), 171*190cef3dSDag-Erling Smørgrav #endif 172*190cef3dSDag-Erling Smørgrav #ifdef __NR_geteuid32 173*190cef3dSDag-Erling Smørgrav SC_ALLOW(__NR_geteuid32), 174*190cef3dSDag-Erling Smørgrav #endif 175557f75e5SDag-Erling Smørgrav #ifdef __NR_getpgid 176d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_getpgid), 177557f75e5SDag-Erling Smørgrav #endif 178557f75e5SDag-Erling Smørgrav #ifdef __NR_getpid 179d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_getpid), 180557f75e5SDag-Erling Smørgrav #endif 181acc1a9efSDag-Erling Smørgrav #ifdef __NR_getrandom 182d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_getrandom), 183acc1a9efSDag-Erling Smørgrav #endif 184557f75e5SDag-Erling Smørgrav #ifdef __NR_gettimeofday 185d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_gettimeofday), 186557f75e5SDag-Erling Smørgrav #endif 187*190cef3dSDag-Erling Smørgrav #ifdef __NR_getuid 188*190cef3dSDag-Erling Smørgrav SC_ALLOW(__NR_getuid), 189*190cef3dSDag-Erling Smørgrav #endif 190*190cef3dSDag-Erling Smørgrav #ifdef __NR_getuid32 191*190cef3dSDag-Erling Smørgrav SC_ALLOW(__NR_getuid32), 192*190cef3dSDag-Erling Smørgrav #endif 193557f75e5SDag-Erling Smørgrav #ifdef __NR_madvise 194d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_madvise), 19558d83921SDag-Erling Smørgrav #endif 19658d83921SDag-Erling Smørgrav #ifdef __NR_mmap 197d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_mmap), 19858d83921SDag-Erling Smørgrav #endif 199557f75e5SDag-Erling Smørgrav #ifdef __NR_mmap2 200d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_mmap2), 201a0ee8cc6SDag-Erling Smørgrav #endif 202557f75e5SDag-Erling Smørgrav #ifdef __NR_mremap 203d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_mremap), 204557f75e5SDag-Erling Smørgrav #endif 205557f75e5SDag-Erling Smørgrav #ifdef __NR_munmap 206d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_munmap), 207557f75e5SDag-Erling Smørgrav #endif 208*190cef3dSDag-Erling Smørgrav #ifdef __NR_nanosleep 209*190cef3dSDag-Erling Smørgrav SC_ALLOW(__NR_nanosleep), 210*190cef3dSDag-Erling Smørgrav #endif 211557f75e5SDag-Erling Smørgrav #ifdef __NR__newselect 212d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR__newselect), 213557f75e5SDag-Erling Smørgrav #endif 214557f75e5SDag-Erling Smørgrav #ifdef __NR_poll 215d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_poll), 216557f75e5SDag-Erling Smørgrav #endif 217557f75e5SDag-Erling Smørgrav #ifdef __NR_pselect6 218d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_pselect6), 219557f75e5SDag-Erling Smørgrav #endif 220557f75e5SDag-Erling Smørgrav #ifdef __NR_read 221d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_read), 222557f75e5SDag-Erling Smørgrav #endif 22358d83921SDag-Erling Smørgrav #ifdef __NR_rt_sigprocmask 224d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_rt_sigprocmask), 225557f75e5SDag-Erling Smørgrav #endif 226557f75e5SDag-Erling Smørgrav #ifdef __NR_select 227d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_select), 228557f75e5SDag-Erling Smørgrav #endif 229557f75e5SDag-Erling Smørgrav #ifdef __NR_shutdown 230d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_shutdown), 231557f75e5SDag-Erling Smørgrav #endif 232557f75e5SDag-Erling Smørgrav #ifdef __NR_sigprocmask 233d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_sigprocmask), 23458d83921SDag-Erling Smørgrav #endif 235557f75e5SDag-Erling Smørgrav #ifdef __NR_time 236d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_time), 237557f75e5SDag-Erling Smørgrav #endif 238557f75e5SDag-Erling Smørgrav #ifdef __NR_write 239d93a896eSDag-Erling Smørgrav SC_ALLOW(__NR_write), 240557f75e5SDag-Erling Smørgrav #endif 241557f75e5SDag-Erling Smørgrav #ifdef __NR_socketcall 242d93a896eSDag-Erling Smørgrav SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN), 2434f52dfbbSDag-Erling Smørgrav SC_DENY(__NR_socketcall, EACCES), 244d93a896eSDag-Erling Smørgrav #endif 245d93a896eSDag-Erling Smørgrav #if defined(__NR_ioctl) && defined(__s390__) 246d93a896eSDag-Erling Smørgrav /* Allow ioctls for ICA crypto card on s390 */ 247d93a896eSDag-Erling Smørgrav SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK), 248d93a896eSDag-Erling Smørgrav SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO), 249d93a896eSDag-Erling Smørgrav SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), 250d93a896eSDag-Erling Smørgrav #endif 251d93a896eSDag-Erling Smørgrav #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) 252d93a896eSDag-Erling Smørgrav /* 253d93a896eSDag-Erling Smørgrav * On Linux x32, the clock_gettime VDSO falls back to the 254d93a896eSDag-Erling Smørgrav * x86-64 syscall under some circumstances, e.g. 255d93a896eSDag-Erling Smørgrav * https://bugs.debian.org/849923 256d93a896eSDag-Erling Smørgrav */ 2574f52dfbbSDag-Erling Smørgrav SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT), 258557f75e5SDag-Erling Smørgrav #endif 259557f75e5SDag-Erling Smørgrav 260557f75e5SDag-Erling Smørgrav /* Default deny */ 26158d83921SDag-Erling Smørgrav BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), 26258d83921SDag-Erling Smørgrav }; 26358d83921SDag-Erling Smørgrav 26458d83921SDag-Erling Smørgrav static const struct sock_fprog preauth_program = { 26558d83921SDag-Erling Smørgrav .len = (unsigned short)(sizeof(preauth_insns)/sizeof(preauth_insns[0])), 26658d83921SDag-Erling Smørgrav .filter = (struct sock_filter *)preauth_insns, 26758d83921SDag-Erling Smørgrav }; 26858d83921SDag-Erling Smørgrav 26958d83921SDag-Erling Smørgrav struct ssh_sandbox { 27058d83921SDag-Erling Smørgrav pid_t child_pid; 27158d83921SDag-Erling Smørgrav }; 27258d83921SDag-Erling Smørgrav 27358d83921SDag-Erling Smørgrav struct ssh_sandbox * 274f7167e0eSDag-Erling Smørgrav ssh_sandbox_init(struct monitor *monitor) 27558d83921SDag-Erling Smørgrav { 27658d83921SDag-Erling Smørgrav struct ssh_sandbox *box; 27758d83921SDag-Erling Smørgrav 27858d83921SDag-Erling Smørgrav /* 27958d83921SDag-Erling Smørgrav * Strictly, we don't need to maintain any state here but we need 28058d83921SDag-Erling Smørgrav * to return non-NULL to satisfy the API. 28158d83921SDag-Erling Smørgrav */ 28258d83921SDag-Erling Smørgrav debug3("%s: preparing seccomp filter sandbox", __func__); 28358d83921SDag-Erling Smørgrav box = xcalloc(1, sizeof(*box)); 28458d83921SDag-Erling Smørgrav box->child_pid = 0; 28558d83921SDag-Erling Smørgrav 28658d83921SDag-Erling Smørgrav return box; 28758d83921SDag-Erling Smørgrav } 28858d83921SDag-Erling Smørgrav 28958d83921SDag-Erling Smørgrav #ifdef SANDBOX_SECCOMP_FILTER_DEBUG 29058d83921SDag-Erling Smørgrav extern struct monitor *pmonitor; 29158d83921SDag-Erling Smørgrav void mm_log_handler(LogLevel level, const char *msg, void *ctx); 29258d83921SDag-Erling Smørgrav 29358d83921SDag-Erling Smørgrav static void 29458d83921SDag-Erling Smørgrav ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context) 29558d83921SDag-Erling Smørgrav { 29658d83921SDag-Erling Smørgrav char msg[256]; 29758d83921SDag-Erling Smørgrav 29858d83921SDag-Erling Smørgrav snprintf(msg, sizeof(msg), 29958d83921SDag-Erling Smørgrav "%s: unexpected system call (arch:0x%x,syscall:%d @ %p)", 30058d83921SDag-Erling Smørgrav __func__, info->si_arch, info->si_syscall, info->si_call_addr); 30158d83921SDag-Erling Smørgrav mm_log_handler(SYSLOG_LEVEL_FATAL, msg, pmonitor); 30258d83921SDag-Erling Smørgrav _exit(1); 30358d83921SDag-Erling Smørgrav } 30458d83921SDag-Erling Smørgrav 30558d83921SDag-Erling Smørgrav static void 30658d83921SDag-Erling Smørgrav ssh_sandbox_child_debugging(void) 30758d83921SDag-Erling Smørgrav { 30858d83921SDag-Erling Smørgrav struct sigaction act; 30958d83921SDag-Erling Smørgrav sigset_t mask; 31058d83921SDag-Erling Smørgrav 31158d83921SDag-Erling Smørgrav debug3("%s: installing SIGSYS handler", __func__); 31258d83921SDag-Erling Smørgrav memset(&act, 0, sizeof(act)); 31358d83921SDag-Erling Smørgrav sigemptyset(&mask); 31458d83921SDag-Erling Smørgrav sigaddset(&mask, SIGSYS); 31558d83921SDag-Erling Smørgrav 31658d83921SDag-Erling Smørgrav act.sa_sigaction = &ssh_sandbox_violation; 31758d83921SDag-Erling Smørgrav act.sa_flags = SA_SIGINFO; 31858d83921SDag-Erling Smørgrav if (sigaction(SIGSYS, &act, NULL) == -1) 31958d83921SDag-Erling Smørgrav fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); 32058d83921SDag-Erling Smørgrav if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) 32158d83921SDag-Erling Smørgrav fatal("%s: sigprocmask(SIGSYS): %s", 32258d83921SDag-Erling Smørgrav __func__, strerror(errno)); 32358d83921SDag-Erling Smørgrav } 32458d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 32558d83921SDag-Erling Smørgrav 32658d83921SDag-Erling Smørgrav void 32758d83921SDag-Erling Smørgrav ssh_sandbox_child(struct ssh_sandbox *box) 32858d83921SDag-Erling Smørgrav { 32958d83921SDag-Erling Smørgrav struct rlimit rl_zero; 33058d83921SDag-Erling Smørgrav int nnp_failed = 0; 33158d83921SDag-Erling Smørgrav 33258d83921SDag-Erling Smørgrav /* Set rlimits for completeness if possible. */ 33358d83921SDag-Erling Smørgrav rl_zero.rlim_cur = rl_zero.rlim_max = 0; 33458d83921SDag-Erling Smørgrav if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) 33558d83921SDag-Erling Smørgrav fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", 33658d83921SDag-Erling Smørgrav __func__, strerror(errno)); 33758d83921SDag-Erling Smørgrav if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) 33858d83921SDag-Erling Smørgrav fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", 33958d83921SDag-Erling Smørgrav __func__, strerror(errno)); 34058d83921SDag-Erling Smørgrav if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) 34158d83921SDag-Erling Smørgrav fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", 34258d83921SDag-Erling Smørgrav __func__, strerror(errno)); 34358d83921SDag-Erling Smørgrav 34458d83921SDag-Erling Smørgrav #ifdef SANDBOX_SECCOMP_FILTER_DEBUG 34558d83921SDag-Erling Smørgrav ssh_sandbox_child_debugging(); 34658d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 34758d83921SDag-Erling Smørgrav 34858d83921SDag-Erling Smørgrav debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); 34958d83921SDag-Erling Smørgrav if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) { 35058d83921SDag-Erling Smørgrav debug("%s: prctl(PR_SET_NO_NEW_PRIVS): %s", 35158d83921SDag-Erling Smørgrav __func__, strerror(errno)); 35258d83921SDag-Erling Smørgrav nnp_failed = 1; 35358d83921SDag-Erling Smørgrav } 35458d83921SDag-Erling Smørgrav debug3("%s: attaching seccomp filter program", __func__); 35558d83921SDag-Erling Smørgrav if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1) 35658d83921SDag-Erling Smørgrav debug("%s: prctl(PR_SET_SECCOMP): %s", 35758d83921SDag-Erling Smørgrav __func__, strerror(errno)); 35858d83921SDag-Erling Smørgrav else if (nnp_failed) 35958d83921SDag-Erling Smørgrav fatal("%s: SECCOMP_MODE_FILTER activated but " 36058d83921SDag-Erling Smørgrav "PR_SET_NO_NEW_PRIVS failed", __func__); 36158d83921SDag-Erling Smørgrav } 36258d83921SDag-Erling Smørgrav 36358d83921SDag-Erling Smørgrav void 36458d83921SDag-Erling Smørgrav ssh_sandbox_parent_finish(struct ssh_sandbox *box) 36558d83921SDag-Erling Smørgrav { 36658d83921SDag-Erling Smørgrav free(box); 36758d83921SDag-Erling Smørgrav debug3("%s: finished", __func__); 36858d83921SDag-Erling Smørgrav } 36958d83921SDag-Erling Smørgrav 37058d83921SDag-Erling Smørgrav void 37158d83921SDag-Erling Smørgrav ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) 37258d83921SDag-Erling Smørgrav { 37358d83921SDag-Erling Smørgrav box->child_pid = child_pid; 37458d83921SDag-Erling Smørgrav } 37558d83921SDag-Erling Smørgrav 37658d83921SDag-Erling Smørgrav #endif /* SANDBOX_SECCOMP_FILTER */ 377