14 #ifndef _LARGEFILE64_SOURCE
19 #define _LARGEFILE64_SOURCE
29 #define MALLOC_MP_LIM (20*1024*1024)
44 #include "ext/tor_queue.h"
46 #include "ext/siphash.h"
48 #define DEBUGGING_CLOSE
50 #if defined(USE_LIBSECCOMP)
53 #include <sys/syscall.h>
54 #include <sys/types.h>
56 #include <sys/epoll.h>
57 #include <sys/prctl.h>
58 #include <linux/futex.h>
61 #ifdef ENABLE_FRAGILE_HARDENING
62 #include <sys/ptrace.h>
73 #ifdef HAVE_GNU_LIBC_VERSION_H
74 #include <gnu/libc-version.h>
76 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
77 #include <linux/netfilter_ipv4.h>
79 #ifdef HAVE_LINUX_IF_H
82 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
83 #include <linux/netfilter_ipv6/ip6_tables.h>
86 #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
87 defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
89 #define BACKTRACE_PRIVATE
100 #if defined(__i386__)
102 #define REG_SYSCALL REG_EAX
103 #define M_SYSCALL gregs[REG_SYSCALL]
108 #elif defined(__x86_64__)
110 #define REG_SYSCALL REG_RAX
111 #define M_SYSCALL gregs[REG_SYSCALL]
113 #elif defined(__arm__)
115 #define M_SYSCALL arm_r7
117 #elif defined(__aarch64__) && defined(__LP64__)
119 #define REG_SYSCALL 8
120 #define M_SYSCALL regs[REG_SYSCALL]
125 #define SYSCALL_NAME_DEBUGGING
129 static int sandbox_active = 0;
134 #define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0})
135 #define SCMP_CMP_STR(a,b,c) \
136 ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0})
137 #define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)})
142 #define SCMP_CMP_MASKED(a,b,c) \
143 SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c))
148 #define SCMP_CMP_LOWER32_EQ(a,b) \
149 SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, 0xFFFFFFFF, (unsigned int)(b))
154 static int filter_nopar_gen[] = {
157 #ifdef __NR_clock_gettime64
158 SCMP_SYS(clock_gettime64),
160 SCMP_SYS(clock_gettime),
168 SCMP_SYS(epoll_create),
169 SCMP_SYS(epoll_wait),
170 #ifdef __NR_epoll_pwait
171 SCMP_SYS(epoll_pwait),
193 SCMP_SYS(getdents64),
195 #ifdef __NR_getegid32
199 #ifdef __NR_geteuid32
207 #ifdef ENABLE_FRAGILE_HARDENING
210 #ifdef __NR_getrlimit
213 SCMP_SYS(gettimeofday),
232 #ifdef __NR_nanosleep
238 #ifdef __NR_prlimit64
242 SCMP_SYS(rt_sigreturn),
246 SCMP_SYS(sched_getaffinity),
247 #ifdef __NR_sched_yield
248 SCMP_SYS(sched_yield),
251 SCMP_SYS(set_robust_list),
252 #ifdef __NR_setrlimit
256 #ifdef __NR_sigaltstack
257 SCMP_SYS(sigaltstack),
259 #ifdef __NR_sigreturn
263 #if defined(__i386__) && defined(__NR_statx)
270 SCMP_SYS(exit_group),
279 #ifdef __NR_getrandom
300 SCMP_SYS(getsockname),
302 #ifdef __NR_getpeername
303 SCMP_SYS(getpeername),
320 #define PHONY_OPENDIR_SYSCALL -2
324 #define seccomp_rule_add_0(ctx,act,call) \
325 seccomp_rule_add((ctx),(act),(call),0)
326 #define seccomp_rule_add_1(ctx,act,call,f1) \
327 seccomp_rule_add((ctx),(act),(call),1,(f1))
328 #define seccomp_rule_add_2(ctx,act,call,f1,f2) \
329 seccomp_rule_add((ctx),(act),(call),2,(f1),(f2))
330 #define seccomp_rule_add_3(ctx,act,call,f1,f2,f3) \
331 seccomp_rule_add((ctx),(act),(call),3,(f1),(f2),(f3))
332 #define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \
333 seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4))
335 static const char *sandbox_get_interned_string(
const char *str);
346 int param[] = { SIGINT, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, SIGHUP, SIGCHLD,
347 SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, SIGIO,
355 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction),
356 SCMP_CMP(0, SCMP_CMP_EQ, param[i]));
374 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time),
375 SCMP_CMP(0, SCMP_CMP_EQ, 0));
390 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall),
391 SCMP_CMP(0, SCMP_CMP_EQ, 18));
397 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4),
398 SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0));
417 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
418 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ),
419 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE));
424 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
425 SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE),
426 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE));
431 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
432 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
433 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS));
438 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
439 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
440 SCMP_CMP(3, SCMP_CMP_EQ,MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK));
445 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
446 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
447 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE));
452 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
453 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
454 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS));
459 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
460 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_EXEC),
461 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_DENYWRITE));
470 #ifdef HAVE_GNU_LIBC_VERSION_H
471 #ifdef HAVE_GNU_GET_LIBC_VERSION
472 #define CHECK_LIBC_VERSION
479 is_libc_at_least(
int major,
int minor)
481 #ifdef CHECK_LIBC_VERSION
482 const char *version = gnu_get_libc_version();
489 tor_sscanf(version,
"%d.%d", &libc_major, &libc_minor);
490 if (libc_major > major)
492 else if (libc_major == major && libc_minor >= minor)
506 libc_uses_openat_for_open(
void)
508 return is_libc_at_least(2, 26);
514 libc_uses_openat_for_opendir(
void)
517 return is_libc_at_least(2, 27) ||
518 (is_libc_at_least(2, 15) && !is_libc_at_least(2, 22));
524 allow_file_open(scmp_filter_ctx ctx,
int use_openat,
const char *file)
527 return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
528 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
529 SCMP_CMP_STR(1, SCMP_CMP_EQ, file));
531 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),
532 SCMP_CMP_STR(0, SCMP_CMP_EQ, file));
546 int use_openat = libc_uses_openat_for_open();
548 #ifdef ENABLE_FRAGILE_HARDENING
553 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open));
555 log_err(
LD_BUG,
"(Sandbox) failed to add open syscall, received "
556 "libseccomp error %d", rc);
567 for (elem = filter; elem != NULL; elem = elem->next) {
568 smp_param_t *param = elem->param;
570 if (param != NULL && param->prot == 1 && param->syscall
572 rc = allow_file_open(ctx, use_openat, param->value);
574 log_err(
LD_BUG,
"(Sandbox) failed to add open syscall, received "
575 "libseccomp error %d", rc);
591 for (elem = filter; elem != NULL; elem = elem->next) {
592 smp_param_t *param = elem->param;
594 if (param != NULL && param->prot == 1 && param->syscall
595 == SCMP_SYS(chmod)) {
596 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod),
597 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
599 log_err(
LD_BUG,
"(Sandbox) failed to add chmod syscall, received "
600 "libseccomp error %d", rc);
616 for (elem = filter; elem != NULL; elem = elem->next) {
617 smp_param_t *param = elem->param;
619 if (param != NULL && param->prot == 1 && param->syscall
620 == SCMP_SYS(fchmodat)) {
621 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchmodat),
622 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
623 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value));
625 log_err(
LD_BUG,
"(Sandbox) failed to add fchmodat syscall, received "
626 "libseccomp error %d", rc);
643 for (elem = filter; elem != NULL; elem = elem->next) {
644 smp_param_t *param = elem->param;
646 if (param != NULL && param->prot == 1 && param->syscall
647 == SCMP_SYS(chown32)) {
648 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown32),
649 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
651 log_err(
LD_BUG,
"(Sandbox) failed to add chown32 syscall, received "
652 "libseccomp error %d", rc);
668 for (elem = filter; elem != NULL; elem = elem->next) {
669 smp_param_t *param = elem->param;
671 if (param != NULL && param->prot == 1 && param->syscall
672 == SCMP_SYS(chown)) {
673 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown),
674 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
676 log_err(
LD_BUG,
"(Sandbox) failed to add chown syscall, received "
677 "libseccomp error %d", rc);
694 for (elem = filter; elem != NULL; elem = elem->next) {
695 smp_param_t *param = elem->param;
697 if (param != NULL && param->prot == 1 && param->syscall
698 == SCMP_SYS(fchownat)) {
699 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchownat),
700 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
701 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value));
703 log_err(
LD_BUG,
"(Sandbox) failed to add fchownat syscall, received "
704 "libseccomp error %d", rc);
724 for (elem = filter; elem != NULL; elem = elem->next) {
725 smp_param_t *param = elem->param;
727 if (param != NULL && param->prot == 1 &&
728 param->syscall == SCMP_SYS(rename)) {
730 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename),
731 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value),
732 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2));
734 log_err(
LD_BUG,
"(Sandbox) failed to add rename syscall, received "
735 "libseccomp error %d", rc);
755 for (elem = filter; elem != NULL; elem = elem->next) {
756 smp_param_t *param = elem->param;
758 if (param != NULL && param->prot == 1 &&
759 param->syscall == SCMP_SYS(renameat)) {
761 rc = seccomp_rule_add_4(ctx, SCMP_ACT_ALLOW, SCMP_SYS(renameat),
762 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
763 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
764 SCMP_CMP_LOWER32_EQ(2, AT_FDCWD),
765 SCMP_CMP_STR(3, SCMP_CMP_EQ, param->value2));
767 log_err(
LD_BUG,
"(Sandbox) failed to add renameat syscall, received "
768 "libseccomp error %d", rc);
788 for (elem = filter; elem != NULL; elem = elem->next) {
789 smp_param_t *param = elem->param;
791 if (param != NULL && param->prot == 1 && param->syscall
792 == SCMP_SYS(openat)) {
793 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
794 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
795 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
796 SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
799 log_err(
LD_BUG,
"(Sandbox) failed to add openat syscall, received "
800 "libseccomp error %d", rc);
816 for (elem = filter; elem != NULL; elem = elem->next) {
817 smp_param_t *param = elem->param;
819 if (param != NULL && param->prot == 1 && param->syscall
820 == PHONY_OPENDIR_SYSCALL) {
821 rc = allow_file_open(ctx, libc_uses_openat_for_opendir(), param->value);
823 log_err(
LD_BUG,
"(Sandbox) failed to add openat syscall, received "
824 "libseccomp error %d", rc);
833 #ifdef ENABLE_FRAGILE_HARDENING
842 pid_t pid = getpid();
845 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace),
846 SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_ATTACH),
847 SCMP_CMP(1, SCMP_CMP_EQ, pid));
851 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace),
852 SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_GETREGS),
853 SCMP_CMP(1, SCMP_CMP_EQ, pid));
873 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket));
878 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
879 SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
880 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM));
884 for (i = 0; i < 2; ++i) {
885 const int pf = i ? PF_INET : PF_INET6;
886 for (j=0; j < 3; ++j) {
887 const int type = (j == 0) ? SOCK_STREAM :
889 const int protocol = (j == 0) ? IPPROTO_TCP :
890 (j == 1) ? IPPROTO_IP :
892 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
893 SCMP_CMP(0, SCMP_CMP_EQ, pf),
894 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, type),
895 SCMP_CMP(2, SCMP_CMP_EQ, protocol));
902 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
903 SCMP_CMP(0, SCMP_CMP_EQ, PF_INET),
904 SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM),
905 SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP));
910 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
911 SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
912 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM),
913 SCMP_CMP(2, SCMP_CMP_EQ, 0));
917 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
918 SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
919 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_DGRAM),
920 SCMP_CMP(2, SCMP_CMP_EQ, 0));
924 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
925 SCMP_CMP(0, SCMP_CMP_EQ, PF_NETLINK),
926 SCMP_CMP_MASKED(1, SOCK_CLOEXEC, SOCK_RAW),
927 SCMP_CMP(2, SCMP_CMP_EQ, 0));
945 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair));
950 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair),
951 SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
952 SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC));
959 #ifdef HAVE_KIST_SUPPORT
961 #include <linux/sockios.h>
969 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl),
970 SCMP_CMP(1, SCMP_CMP_EQ, SIOCOUTQNSD));
989 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt));
994 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
995 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
996 SCMP_CMP(2, SCMP_CMP_EQ, SO_REUSEADDR));
1000 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
1001 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
1002 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
1006 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
1007 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
1008 SCMP_CMP(2, SCMP_CMP_EQ, SO_RCVBUF));
1013 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
1014 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
1015 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUFFORCE));
1020 #ifdef IP_TRANSPARENT
1021 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
1022 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
1023 SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT));
1029 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
1030 SCMP_CMP(1, SCMP_CMP_EQ, IPPROTO_IPV6),
1031 SCMP_CMP(2, SCMP_CMP_EQ, IPV6_V6ONLY));
1036 #ifdef IP_BIND_ADDRESS_NO_PORT
1037 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
1038 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
1039 SCMP_CMP(2, SCMP_CMP_EQ, IP_BIND_ADDRESS_NO_PORT));
1058 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt));
1063 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
1064 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
1065 SCMP_CMP(2, SCMP_CMP_EQ, SO_ERROR));
1069 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
1070 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
1071 SCMP_CMP(2, SCMP_CMP_EQ, SO_ACCEPTCONN));
1076 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
1077 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
1078 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
1083 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
1084 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
1085 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
1086 SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST));
1091 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
1092 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
1093 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6),
1094 SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST));
1099 #ifdef HAVE_KIST_SUPPORT
1100 #include <netinet/tcp.h>
1101 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
1102 SCMP_CMP(1, SCMP_CMP_EQ, SOL_TCP),
1103 SCMP_CMP(2, SCMP_CMP_EQ, TCP_INFO));
1122 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
1123 SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL));
1127 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
1128 SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL),
1129 SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK));
1133 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
1134 SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD));
1138 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
1139 SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD),
1140 SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC));
1160 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
1161 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD));
1165 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
1166 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD));
1170 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
1171 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL));
1191 #ifdef ENABLE_FRAGILE_HARDENING
1192 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
1193 SCMP_CMP(0, SCMP_CMP_EQ, PR_GET_DUMPABLE));
1197 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
1198 SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_PTRACER));
1203 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
1204 SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE));
1224 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1225 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ));
1229 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1230 SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE));
1242 sb_rt_sigprocmask(scmp_filter_ctx ctx,
sandbox_cfg_t *filter)
1247 #ifdef ENABLE_FRAGILE_HARDENING
1248 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
1249 SCMP_CMP(0, SCMP_CMP_EQ, SIG_BLOCK));
1254 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
1255 SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK));
1259 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
1260 SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK));
1279 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1280 SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB));
1284 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1285 SCMP_CMP(1, SCMP_CMP_EQ, LOCK_UN));
1303 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1304 SCMP_CMP(1, SCMP_CMP_EQ,
1305 FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME));
1309 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1310 SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
1314 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1315 SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE));
1334 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap),
1335 SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE));
1354 for (elem = filter; elem != NULL; elem = elem->next) {
1355 smp_param_t *param = elem->param;
1357 if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
1358 || param->syscall == SCMP_SYS(stat64))) {
1359 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64),
1360 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
1362 log_err(
LD_BUG,
"(Sandbox) failed to add stat64 syscall, received "
1363 "libseccomp error %d", rc);
1379 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(kill),
1380 SCMP_CMP(1, SCMP_CMP_EQ, 0));
1390 static sandbox_filter_func_t filter_func[] = {
1411 #ifdef ENABLE_FRAGILE_HARDENING
1433 #ifdef HAVE_KIST_SUPPORT
1448 const char *interned = sandbox_get_interned_string(str);
1450 if (sandbox_active && str != NULL && interned == NULL) {
1451 log_warn(
LD_BUG,
"No interned sandbox parameter found for %s", str);
1454 return interned ? interned : str;
1462 sandbox_interned_string_is_missing(
const char *str)
1464 return sandbox_active && sandbox_get_interned_string(str) == NULL;
1473 sandbox_get_interned_string(
const char *str)
1480 for (elem = filter_dynamic; elem != NULL; elem = elem->next) {
1481 smp_param_t *param = elem->param;
1484 if (!strcmp(str, (
char*)(param->value))) {
1485 return (
char*)param->value;
1487 if (param->value2 && !strcmp(str, (
char*)param->value2)) {
1488 return (
char*)param->value2;
1498 prot_strings_helper(strmap_t *locations,
1499 char **pr_mem_next_p,
1500 size_t *pr_mem_left_p,
1510 param_val = (
char*) *value_p;
1511 param_size = strlen(param_val) + 1;
1512 location = strmap_get(locations, param_val);
1517 *value_p = location;
1519 }
else if (*pr_mem_left_p >= param_size) {
1521 location = *pr_mem_next_p;
1522 memcpy(location, param_val, param_size);
1526 *value_p = location;
1528 strmap_set(locations, location, location);
1531 *pr_mem_next_p += param_size;
1532 *pr_mem_left_p -= param_size;
1535 log_err(
LD_BUG,
"(Sandbox) insufficient protected memory!");
1550 size_t pr_mem_size = 0, pr_mem_left = 0;
1551 char *pr_mem_next = NULL, *pr_mem_base;
1553 strmap_t *locations = NULL;
1556 for (el = cfg; el != NULL; el = el->next) {
1557 pr_mem_size += strlen((
char*) el->param->value) + 1;
1558 if (el->param->value2)
1559 pr_mem_size += strlen((
char*) el->param->value2) + 1;
1563 pr_mem_base = (
char*) mmap(NULL,
MALLOC_MP_LIM + pr_mem_size,
1564 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
1565 if (pr_mem_base == MAP_FAILED) {
1566 log_err(
LD_BUG,
"(Sandbox) failed allocate protected memory! mmap: %s",
1573 pr_mem_left = pr_mem_size;
1575 locations = strmap_new();
1578 for (el = cfg; el != NULL; el = el->next) {
1579 if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1580 &el->param->value) < 0) {
1584 if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1585 &el->param->value2) < 0) {
1589 el->param->prot = 1;
1593 if (mprotect(pr_mem_base,
MALLOC_MP_LIM + pr_mem_size, PROT_READ)) {
1594 log_err(
LD_BUG,
"(Sandbox) failed to protect memory! mprotect: %s",
1604 ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(mremap),
1605 SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1607 log_err(
LD_BUG,
"(Sandbox) mremap protected memory filter fail!");
1612 ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(munmap),
1613 SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1615 log_err(
LD_BUG,
"(Sandbox) munmap protected memory filter fail!");
1629 ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1630 SCMP_CMP(0, SCMP_CMP_LT, (intptr_t) pr_mem_base),
1632 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1634 log_err(
LD_BUG,
"(Sandbox) mprotect protected memory filter fail (LT)!");
1638 ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1639 SCMP_CMP(0, SCMP_CMP_GT, (intptr_t) pr_mem_base + pr_mem_size +
1642 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1644 log_err(
LD_BUG,
"(Sandbox) mprotect protected memory filter fail (GT)!");
1649 strmap_free(locations, NULL);
1660 new_element2(
int syscall,
char *value,
char *value2)
1662 smp_param_t *param = NULL;
1665 param = elem->param = tor_malloc_zero(
sizeof(smp_param_t));
1667 param->syscall = syscall;
1668 param->value = value;
1669 param->value2 = value2;
1676 new_element(
int syscall,
char *value)
1678 return new_element2(syscall, value, NULL);
1682 #define SCMP_chown SCMP_SYS(chown32)
1683 #elif defined(__aarch64__) && defined(__LP64__)
1684 #define SCMP_chown SCMP_SYS(fchownat)
1686 #define SCMP_chown SCMP_SYS(chown)
1689 #if defined(__aarch64__) && defined(__LP64__)
1690 #define SCMP_chmod SCMP_SYS(fchmodat)
1692 #define SCMP_chmod SCMP_SYS(chmod)
1695 #if defined(__aarch64__) && defined(__LP64__)
1696 #define SCMP_rename SCMP_SYS(renameat)
1698 #define SCMP_rename SCMP_SYS(rename)
1702 #define SCMP_stat SCMP_SYS(stat64)
1704 #define SCMP_stat SCMP_SYS(stat)
1712 elem = new_element(SCMP_stat, file);
1725 elem = new_element(SCMP_SYS(open), file);
1734 sandbox_cfg_allow_chmod_filename(
sandbox_cfg_t **cfg,
char *file)
1738 elem = new_element(SCMP_chmod, file);
1747 sandbox_cfg_allow_chown_filename(
sandbox_cfg_t **cfg,
char *file)
1751 elem = new_element(SCMP_chown, file);
1760 sandbox_cfg_allow_rename(
sandbox_cfg_t **cfg,
char *file1,
char *file2)
1764 elem = new_element2(SCMP_rename, file1, file2);
1777 elem = new_element(SCMP_SYS(openat), file);
1790 elem = new_element(PHONY_OPENDIR_SYSCALL, dir);
1810 rc = filter_func[i](ctx, cfg);
1812 log_err(
LD_BUG,
"(Sandbox) failed to add syscall %d, received libseccomp "
1826 add_noparam_filter(scmp_filter_ctx ctx)
1833 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i]);
1835 log_err(
LD_BUG,
"(Sandbox) failed to add syscall index %d (NR=%d), "
1836 "received libseccomp error %d", i, filter_nopar_gen[i], rc);
1841 if (is_libc_at_least(2, 33)) {
1842 #ifdef __NR_newfstatat
1854 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat));
1856 log_err(
LD_BUG,
"(Sandbox) failed to add newfstatat() syscall; "
1857 "received libseccomp error %d", rc);
1875 scmp_filter_ctx ctx;
1877 ctx = seccomp_init(SCMP_ACT_ERRNO(EPERM));
1879 log_err(
LD_BUG,
"(Sandbox) failed to initialise libseccomp context");
1885 if ((rc = prot_strings(ctx, cfg))) {
1890 if ((rc = add_param_filter(ctx, cfg))) {
1891 log_err(
LD_BUG,
"(Sandbox) failed to add param filters!");
1896 if ((rc = add_noparam_filter(ctx))) {
1897 log_err(
LD_BUG,
"(Sandbox) failed to add param filters!");
1902 if ((rc = seccomp_load(ctx))) {
1903 log_err(
LD_BUG,
"(Sandbox) failed to load: %d (%s)! "
1904 "Are you sure that your kernel has seccomp2 support? The "
1905 "sandbox won't work without it.", rc,
1914 seccomp_release(ctx);
1915 return (rc < 0 ? -rc : rc);
1918 #ifdef SYSCALL_NAME_DEBUGGING
1919 #include "lib/sandbox/linux_syscalls.inc"
1923 get_syscall_name(
int syscall_num)
1926 for (i = 0; SYSCALLS_BY_NUMBER[i].syscall_name; ++i) {
1927 if (SYSCALLS_BY_NUMBER[i].syscall_num == syscall_num)
1928 return SYSCALLS_BY_NUMBER[i].syscall_name;
1932 static char syscall_name_buf[64];
1934 syscall_name_buf,
sizeof(syscall_name_buf));
1935 return syscall_name_buf;
1942 get_syscall_from_ucontext(
const ucontext_t *ctx)
1944 return (
int) ctx->uc_mcontext.M_SYSCALL;
1948 get_syscall_name(
int syscall_num)
1954 get_syscall_from_ucontext(
const ucontext_t *ctx)
1961 #ifdef USE_BACKTRACE
1962 #define MAX_DEPTH 256
1963 static void *syscall_cb_buf[MAX_DEPTH];
1972 sigsys_debugging(
int nr, siginfo_t *info,
void *void_context)
1974 ucontext_t *ctx = (ucontext_t *) (void_context);
1975 const char *syscall_name;
1976 #ifdef USE_BACKTRACE
1979 const int *fds = NULL;
1990 int syscall = get_syscall_from_ucontext(ctx);
1992 #ifdef USE_BACKTRACE
1993 depth = backtrace(syscall_cb_buf, MAX_DEPTH);
1996 clean_backtrace(syscall_cb_buf, depth, ctx);
1999 syscall_name = get_syscall_name(syscall);
2006 #ifdef USE_BACKTRACE
2008 for (i=0; i < n_fds; ++i)
2009 backtrace_symbols_fd(syscall_cb_buf, (
int)depth, fds[i]);
2012 #if defined(DEBUGGING_CLOSE)
2024 install_sigsys_debugging(
void)
2026 struct sigaction act;
2029 memset(&act, 0,
sizeof(act));
2031 sigaddset(&mask, SIGSYS);
2033 act.sa_sigaction = &sigsys_debugging;
2034 act.sa_flags = SA_SIGINFO;
2035 if (sigaction(SIGSYS, &act, NULL) < 0) {
2036 log_err(
LD_BUG,
"(Sandbox) Failed to register SIGSYS signal handler");
2040 if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
2041 log_err(
LD_BUG,
"(Sandbox) Failed call to sigprocmask()");
2058 if (filter_dynamic == NULL) {
2059 filter_dynamic = cfg;
2063 for (elem = filter_dynamic; elem->next != NULL; elem = elem->next)
2073 #ifdef USE_LIBSECCOMP
2082 setenv(
"LIBC_FATAL_STDERR_",
"1", 1);
2084 if (install_sigsys_debugging())
2087 if (install_syscall_filter(cfg))
2090 if (register_cfg(cfg))
2099 return sandbox_active != 0;
2112 #if defined(USE_LIBSECCOMP)
2113 return initialise_libseccomp_sandbox(cfg);
2115 #elif defined(__linux__)
2118 "This version of Tor was built without support for sandboxing. To "
2119 "build with support for sandboxing on Linux, you must have "
2120 "libseccomp and its necessary header files (e.g. seccomp.h).");
2126 "Currently, sandboxing is only implemented on Linux. The feature "
2127 "is disabled on your platform.");
2132 #ifndef USE_LIBSECCOMP
2136 (void)cfg; (void)file;
2143 (void)cfg; (void)file;
2150 (void)cfg; (void)dir;
2157 (void)cfg; (void)file;
2162 sandbox_cfg_allow_chown_filename(
sandbox_cfg_t **cfg,
char *file)
2164 (void)cfg; (void)file;
2169 sandbox_cfg_allow_chmod_filename(
sandbox_cfg_t **cfg,
char *file)
2171 (void)cfg; (void)file;
2176 sandbox_cfg_allow_rename(
sandbox_cfg_t **cfg,
char *file1,
char *file2)
2178 (void)cfg; (void)file1; (void)file2;
Headers for util_malloc.c.
int sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
int sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
int sandbox_init(sandbox_cfg_t *cfg)
int sandbox_is_active(void)
int sandbox_cfg_allow_opendir_dirname(sandbox_cfg_t **cfg, char *dir)
sandbox_cfg_t * sandbox_cfg_new(void)
int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
Header file for sandbox.c.
struct sandbox_cfg_elem_t sandbox_cfg_t
#define sandbox_intern_string(s)
int tor_sscanf(const char *buf, const char *pattern,...)
Definitions for timing-related constants.
int format_dec_number_sigsafe(unsigned long x, char *buf, int buf_len)
void tor_log_err_sigsafe(const char *m,...)
int tor_log_get_sigsafe_err_fds(const int **out)
Integer definitions used throughout Tor.