1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
9 * \brief Code to enable sandboxing.
14 #ifndef _LARGEFILE64_SOURCE
16 * Temporarily required for O_LARGEFILE flag. Needs to be removed
17 * with the libevent fix.
19 #define _LARGEFILE64_SOURCE
20 #endif /* !defined(_LARGEFILE64_SOURCE) */
22 /** Malloc mprotect limit in bytes.
24 * 28/06/2017: This value was increased from 16 MB to 20 MB after we introduced
25 * LZMA support in Tor (0.3.1.1-alpha). We limit our LZMA coder to 16 MB, but
26 * liblzma have a small overhead that we need to compensate for to avoid being
27 * killed by the sandbox.
29 #define MALLOC_MP_LIM (20*1024*1024)
36 #include "lib/sandbox/sandbox.h"
37 #include "lib/container/map.h"
38 #include "lib/err/torerr.h"
39 #include "lib/log/log.h"
40 #include "lib/cc/torint.h"
41 #include "lib/malloc/malloc.h"
42 #include "lib/string/scanf.h"
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
90 #include "lib/err/backtrace.h"
91 #endif /* defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && ... */
98 * Linux 32 bit definitions
100 #if defined(__i386__)
102 #define REG_SYSCALL REG_EAX
103 #define M_SYSCALL gregs[REG_SYSCALL]
106 * Linux 64 bit definitions
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]
122 #endif /* defined(__i386__) || ... */
125 #define SYSCALL_NAME_DEBUGGING
128 /**Determines if at least one sandbox is active.*/
129 static int sandbox_active
= 0;
130 /** Holds the parameter list configuration for the sandbox.*/
131 static sandbox_cfg_t
*filter_dynamic
= NULL
;
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)})
138 /* We use a wrapper here because these masked comparisons seem to be pretty
139 * verbose. Also, it's important to cast to scmp_datum_t before negating the
140 * mask, since otherwise the negation might get applied to a 32 bit value, and
141 * the high bits of the value might get masked out improperly. */
142 #define SCMP_CMP_MASKED(a,b,c) \
143 SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c))
144 /* For negative constants, the rule to add depends on the glibc version. */
145 #define SCMP_CMP_NEG(a,op,b) (libc_negative_constant_needs_cast() ? \
146 (SCMP_CMP((a), (op), (unsigned int)(b))) : \
147 (SCMP_CMP_STR((a), (op), (b))))
149 /** Variable used for storing all syscall numbers that will be allowed with the
150 * stage 1 general Tor sandbox.
152 static int filter_nopar_gen
[] = {
155 #ifdef __NR_clock_gettime64
156 SCMP_SYS(clock_gettime64
),
158 SCMP_SYS(clock_gettime
),
166 SCMP_SYS(epoll_create
),
167 SCMP_SYS(epoll_wait
),
168 #ifdef __NR_epoll_pwait
169 SCMP_SYS(epoll_pwait
),
191 SCMP_SYS(getdents64
),
193 #ifdef __NR_getegid32
197 #ifdef __NR_geteuid32
205 #ifdef ENABLE_FRAGILE_HARDENING
208 #ifdef __NR_getrlimit
211 SCMP_SYS(gettimeofday
),
226 /* XXXX restrict this in the same ways as mmap2 */
230 #ifdef __NR_nanosleep
236 #ifdef __NR_prlimit64
240 SCMP_SYS(rt_sigreturn
),
244 SCMP_SYS(sched_getaffinity
),
245 #ifdef __NR_sched_yield
246 SCMP_SYS(sched_yield
),
249 SCMP_SYS(set_robust_list
),
250 #ifdef __NR_setrlimit
254 #ifdef __NR_sigaltstack
255 SCMP_SYS(sigaltstack
),
257 #ifdef __NR_sigreturn
261 #if defined(__i386__) && defined(__NR_statx)
268 SCMP_SYS(exit_group
),
273 // getaddrinfo uses this..
277 #ifdef __NR_getrandom
286 * These socket syscalls are not required on x86_64 and not supported with
287 * some libseccomp versions (eg: 1.0.1)
298 SCMP_SYS(getsockname
),
300 #ifdef __NR_getpeername
301 SCMP_SYS(getpeername
),
314 /* opendir is not a syscall but it will use either open or openat. We do not
315 * want the decision to allow open/openat to be the callers reponsability, so
316 * we create a phony syscall number for opendir and sb_opendir will choose the
317 * correct syscall. */
318 #define PHONY_OPENDIR_SYSCALL -2
320 /* These macros help avoid the error where the number of filters we add on a
321 * single rule don't match the arg_cnt param. */
322 #define seccomp_rule_add_0(ctx,act,call) \
323 seccomp_rule_add((ctx),(act),(call),0)
324 #define seccomp_rule_add_1(ctx,act,call,f1) \
325 seccomp_rule_add((ctx),(act),(call),1,(f1))
326 #define seccomp_rule_add_2(ctx,act,call,f1,f2) \
327 seccomp_rule_add((ctx),(act),(call),2,(f1),(f2))
328 #define seccomp_rule_add_3(ctx,act,call,f1,f2,f3) \
329 seccomp_rule_add((ctx),(act),(call),3,(f1),(f2),(f3))
330 #define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \
331 seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4))
333 static const char *sandbox_get_interned_string(const char *str
);
336 * Function responsible for setting up the rt_sigaction syscall for
337 * the seccomp filter sandbox.
340 sb_rt_sigaction(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
344 int param
[] = { SIGINT
, SIGTERM
, SIGPIPE
, SIGUSR1
, SIGUSR2
, SIGHUP
, SIGCHLD
,
345 SIGSEGV
, SIGILL
, SIGFPE
, SIGBUS
, SIGSYS
, SIGIO
,
352 for (i
= 0; i
< ARRAY_LENGTH(param
); i
++) {
353 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rt_sigaction
),
354 SCMP_CMP(0, SCMP_CMP_EQ
, param
[i
]));
364 * Function responsible for setting up the time syscall for
365 * the seccomp filter sandbox.
368 sb_time(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
372 return seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(time
),
373 SCMP_CMP(0, SCMP_CMP_EQ
, 0));
375 #endif /* defined(__NR_time) */
378 * Function responsible for setting up the accept4 syscall for
379 * the seccomp filter sandbox.
382 sb_accept4(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
388 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socketcall
),
389 SCMP_CMP(0, SCMP_CMP_EQ
, 18));
393 #endif /* defined(__i386__) */
395 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(accept4
),
396 SCMP_CMP_MASKED(3, SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0));
406 * Function responsible for setting up the mmap2 syscall for
407 * the seccomp filter sandbox.
410 sb_mmap2(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
415 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
416 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
),
417 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
));
422 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
423 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_NONE
),
424 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_ANONYMOUS
|MAP_NORESERVE
));
429 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
430 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
),
431 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_ANONYMOUS
));
436 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
437 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
),
438 SCMP_CMP(3, SCMP_CMP_EQ
,MAP_PRIVATE
|MAP_ANONYMOUS
|MAP_STACK
));
443 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
444 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
),
445 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_FIXED
|MAP_DENYWRITE
));
450 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
451 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
),
452 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_FIXED
|MAP_ANONYMOUS
));
457 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
458 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_EXEC
),
459 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_DENYWRITE
));
466 #endif /* defined(__NR_mmap2) */
468 #ifdef HAVE_GNU_LIBC_VERSION_H
469 #ifdef HAVE_GNU_GET_LIBC_VERSION
470 #define CHECK_LIBC_VERSION
474 /* Return true the libc version is greater or equal than
475 * <b>major</b>.<b>minor</b>. Returns false otherwise. */
477 is_libc_at_least(int major
, int minor
)
479 #ifdef CHECK_LIBC_VERSION
480 const char *version
= gnu_get_libc_version();
487 tor_sscanf(version
, "%d.%d", &libc_major
, &libc_minor
);
488 if (libc_major
> major
)
490 else if (libc_major
== major
&& libc_minor
>= minor
)
494 #else /* !defined(CHECK_LIBC_VERSION) */
498 #endif /* defined(CHECK_LIBC_VERSION) */
501 /* Return true if we think we're running with a libc that uses openat for the
502 * open function on linux. */
504 libc_uses_openat_for_open(void)
506 return is_libc_at_least(2, 26);
509 /* Return true if we think we're running with a libc that uses openat for the
510 * opendir function on linux. */
512 libc_uses_openat_for_opendir(void)
514 // libc 2.27 and above or between 2.15 (inclusive) and 2.22 (exclusive)
515 return is_libc_at_least(2, 27) ||
516 (is_libc_at_least(2, 15) && !is_libc_at_least(2, 22));
519 /* Return true if we think we're running with a libc that needs to cast
520 * negative arguments like AT_FDCWD for seccomp rules. */
522 libc_negative_constant_needs_cast(void)
524 return is_libc_at_least(2, 27);
527 /** Allow a single file to be opened. If <b>use_openat</b> is true,
528 * we're using a libc that remaps all the opens into openats. */
530 allow_file_open(scmp_filter_ctx ctx
, int use_openat
, const char *file
)
533 return seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(openat
),
534 SCMP_CMP_NEG(0, SCMP_CMP_EQ
, AT_FDCWD
),
535 SCMP_CMP_STR(1, SCMP_CMP_EQ
, file
));
537 return seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(open
),
538 SCMP_CMP_STR(0, SCMP_CMP_EQ
, file
));
543 * Function responsible for setting up the open syscall for
544 * the seccomp filter sandbox.
547 sb_open(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
550 sandbox_cfg_t
*elem
= NULL
;
552 int use_openat
= libc_uses_openat_for_open();
554 #ifdef ENABLE_FRAGILE_HARDENING
555 /* AddressSanitizer uses the "open" syscall to access information about the
556 * running process via the filesystem, so that call must be allowed without
557 * restriction or the sanitizer will be unable to execute normally when the
558 * process terminates. */
559 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(open
));
561 log_err(LD_BUG
,"(Sandbox) failed to add open syscall, received "
562 "libseccomp error %d", rc
);
566 /* If glibc also uses only the "open" syscall to open files on this system
567 * there is no need to consider any additional rules. */
572 // for each dynamic parameter filters
573 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
574 smp_param_t
*param
= elem
->param
;
576 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
578 rc
= allow_file_open(ctx
, use_openat
, param
->value
);
580 log_err(LD_BUG
,"(Sandbox) failed to add open syscall, received "
581 "libseccomp error %d", rc
);
591 sb_chmod(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
594 sandbox_cfg_t
*elem
= NULL
;
596 // for each dynamic parameter filters
597 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
598 smp_param_t
*param
= elem
->param
;
600 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
601 == SCMP_SYS(chmod
)) {
602 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(chmod
),
603 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
));
605 log_err(LD_BUG
,"(Sandbox) failed to add chmod syscall, received "
606 "libseccomp error %d", rc
);
617 sb_chown32(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
620 sandbox_cfg_t
*elem
= NULL
;
622 // for each dynamic parameter filters
623 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
624 smp_param_t
*param
= elem
->param
;
626 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
627 == SCMP_SYS(chown32
)) {
628 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(chown32
),
629 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
));
631 log_err(LD_BUG
,"(Sandbox) failed to add chown32 syscall, received "
632 "libseccomp error %d", rc
);
642 sb_chown(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
645 sandbox_cfg_t
*elem
= NULL
;
647 // for each dynamic parameter filters
648 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
649 smp_param_t
*param
= elem
->param
;
651 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
652 == SCMP_SYS(chown
)) {
653 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(chown
),
654 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
));
656 log_err(LD_BUG
,"(Sandbox) failed to add chown syscall, received "
657 "libseccomp error %d", rc
);
665 #endif /* defined(__i386__) */
668 * Function responsible for setting up the rename syscall for
669 * the seccomp filter sandbox.
672 sb_rename(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
675 sandbox_cfg_t
*elem
= NULL
;
677 // for each dynamic parameter filters
678 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
679 smp_param_t
*param
= elem
->param
;
681 if (param
!= NULL
&& param
->prot
== 1 &&
682 param
->syscall
== SCMP_SYS(rename
)) {
684 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rename
),
685 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
),
686 SCMP_CMP_STR(1, SCMP_CMP_EQ
, param
->value2
));
688 log_err(LD_BUG
,"(Sandbox) failed to add rename syscall, received "
689 "libseccomp error %d", rc
);
699 * Function responsible for setting up the openat syscall for
700 * the seccomp filter sandbox.
703 sb_openat(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
706 sandbox_cfg_t
*elem
= NULL
;
708 // for each dynamic parameter filters
709 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
710 smp_param_t
*param
= elem
->param
;
712 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
713 == SCMP_SYS(openat
)) {
714 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(openat
),
715 SCMP_CMP_NEG(0, SCMP_CMP_EQ
, AT_FDCWD
),
716 SCMP_CMP_STR(1, SCMP_CMP_EQ
, param
->value
),
717 SCMP_CMP(2, SCMP_CMP_EQ
, O_RDONLY
|O_NONBLOCK
|O_LARGEFILE
|O_DIRECTORY
|
720 log_err(LD_BUG
,"(Sandbox) failed to add openat syscall, received "
721 "libseccomp error %d", rc
);
731 sb_opendir(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
734 sandbox_cfg_t
*elem
= NULL
;
736 // for each dynamic parameter filters
737 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
738 smp_param_t
*param
= elem
->param
;
740 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
741 == PHONY_OPENDIR_SYSCALL
) {
742 rc
= allow_file_open(ctx
, libc_uses_openat_for_opendir(), param
->value
);
744 log_err(LD_BUG
,"(Sandbox) failed to add openat syscall, received "
745 "libseccomp error %d", rc
);
754 #ifdef ENABLE_FRAGILE_HARDENING
756 * Function responsible for setting up the ptrace syscall for
757 * the seccomp filter sandbox.
760 sb_ptrace(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
763 pid_t pid
= getpid();
766 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(ptrace
),
767 SCMP_CMP(0, SCMP_CMP_EQ
, PTRACE_ATTACH
),
768 SCMP_CMP(1, SCMP_CMP_EQ
, pid
));
772 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(ptrace
),
773 SCMP_CMP(0, SCMP_CMP_EQ
, PTRACE_GETREGS
),
774 SCMP_CMP(1, SCMP_CMP_EQ
, pid
));
783 * Function responsible for setting up the socket syscall for
784 * the seccomp filter sandbox.
787 sb_socket(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
794 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
));
799 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
800 SCMP_CMP(0, SCMP_CMP_EQ
, PF_FILE
),
801 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
|SOCK_NONBLOCK
, SOCK_STREAM
));
805 for (i
= 0; i
< 2; ++i
) {
806 const int pf
= i
? PF_INET
: PF_INET6
;
807 for (j
=0; j
< 3; ++j
) {
808 const int type
= (j
== 0) ? SOCK_STREAM
:
810 const int protocol
= (j
== 0) ? IPPROTO_TCP
:
811 (j
== 1) ? IPPROTO_IP
:
813 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
814 SCMP_CMP(0, SCMP_CMP_EQ
, pf
),
815 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
|SOCK_NONBLOCK
, type
),
816 SCMP_CMP(2, SCMP_CMP_EQ
, protocol
));
823 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
824 SCMP_CMP(0, SCMP_CMP_EQ
, PF_INET
),
825 SCMP_CMP(1, SCMP_CMP_EQ
, SOCK_STREAM
),
826 SCMP_CMP(2, SCMP_CMP_EQ
, IPPROTO_IP
));
829 #endif /* defined(ENABLE_NSS) */
831 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
832 SCMP_CMP(0, SCMP_CMP_EQ
, PF_UNIX
),
833 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
|SOCK_NONBLOCK
, SOCK_STREAM
),
834 SCMP_CMP(2, SCMP_CMP_EQ
, 0));
838 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
839 SCMP_CMP(0, SCMP_CMP_EQ
, PF_UNIX
),
840 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
|SOCK_NONBLOCK
, SOCK_DGRAM
),
841 SCMP_CMP(2, SCMP_CMP_EQ
, 0));
845 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
846 SCMP_CMP(0, SCMP_CMP_EQ
, PF_NETLINK
),
847 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
, SOCK_RAW
),
848 SCMP_CMP(2, SCMP_CMP_EQ
, 0));
856 * Function responsible for setting up the socketpair syscall for
857 * the seccomp filter sandbox.
860 sb_socketpair(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
866 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socketpair
));
871 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socketpair
),
872 SCMP_CMP(0, SCMP_CMP_EQ
, PF_FILE
),
873 SCMP_CMP(1, SCMP_CMP_EQ
, SOCK_STREAM
|SOCK_CLOEXEC
));
880 #ifdef HAVE_KIST_SUPPORT
882 #include <linux/sockios.h>
885 sb_ioctl(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
890 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(ioctl
),
891 SCMP_CMP(1, SCMP_CMP_EQ
, SIOCOUTQNSD
));
897 #endif /* defined(HAVE_KIST_SUPPORT) */
900 * Function responsible for setting up the setsockopt syscall for
901 * the seccomp filter sandbox.
904 sb_setsockopt(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
910 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
));
915 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
916 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
917 SCMP_CMP(2, SCMP_CMP_EQ
, SO_REUSEADDR
));
921 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
922 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
923 SCMP_CMP(2, SCMP_CMP_EQ
, SO_SNDBUF
));
927 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
928 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
929 SCMP_CMP(2, SCMP_CMP_EQ
, SO_RCVBUF
));
934 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
935 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
936 SCMP_CMP(2, SCMP_CMP_EQ
, SO_SNDBUFFORCE
));
939 #endif /* defined(HAVE_SYSTEMD) */
941 #ifdef IP_TRANSPARENT
942 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
943 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_IP
),
944 SCMP_CMP(2, SCMP_CMP_EQ
, IP_TRANSPARENT
));
947 #endif /* defined(IP_TRANSPARENT) */
950 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
951 SCMP_CMP(1, SCMP_CMP_EQ
, IPPROTO_IPV6
),
952 SCMP_CMP(2, SCMP_CMP_EQ
, IPV6_V6ONLY
));
955 #endif /* defined(IPV6_V6ONLY) */
961 * Function responsible for setting up the getsockopt syscall for
962 * the seccomp filter sandbox.
965 sb_getsockopt(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
971 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
));
976 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
977 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
978 SCMP_CMP(2, SCMP_CMP_EQ
, SO_ERROR
));
982 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
983 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
984 SCMP_CMP(2, SCMP_CMP_EQ
, SO_ACCEPTCONN
));
989 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
990 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
991 SCMP_CMP(2, SCMP_CMP_EQ
, SO_SNDBUF
));
994 #endif /* defined(HAVE_SYSTEMD) */
996 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
997 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
998 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_IP
),
999 SCMP_CMP(2, SCMP_CMP_EQ
, SO_ORIGINAL_DST
));
1002 #endif /* defined(HAVE_LINUX_NETFILTER_IPV4_H) */
1004 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
1005 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
1006 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_IPV6
),
1007 SCMP_CMP(2, SCMP_CMP_EQ
, IP6T_SO_ORIGINAL_DST
));
1010 #endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */
1012 #ifdef HAVE_KIST_SUPPORT
1013 #include <netinet/tcp.h>
1014 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
1015 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_TCP
),
1016 SCMP_CMP(2, SCMP_CMP_EQ
, TCP_INFO
));
1019 #endif /* defined(HAVE_KIST_SUPPORT) */
1026 * Function responsible for setting up the fcntl64 syscall for
1027 * the seccomp filter sandbox.
1030 sb_fcntl64(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1035 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
),
1036 SCMP_CMP(1, SCMP_CMP_EQ
, F_GETFL
));
1040 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
),
1041 SCMP_CMP(1, SCMP_CMP_EQ
, F_SETFL
),
1042 SCMP_CMP(2, SCMP_CMP_EQ
, O_RDWR
|O_NONBLOCK
));
1046 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
),
1047 SCMP_CMP(1, SCMP_CMP_EQ
, F_GETFD
));
1051 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
),
1052 SCMP_CMP(1, SCMP_CMP_EQ
, F_SETFD
),
1053 SCMP_CMP(2, SCMP_CMP_EQ
, FD_CLOEXEC
));
1059 #endif /* defined(__NR_fcntl64) */
1062 * Function responsible for setting up the epoll_ctl syscall for
1063 * the seccomp filter sandbox.
1065 * Note: basically allows everything but will keep for now..
1068 sb_epoll_ctl(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1073 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(epoll_ctl
),
1074 SCMP_CMP(1, SCMP_CMP_EQ
, EPOLL_CTL_ADD
));
1078 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(epoll_ctl
),
1079 SCMP_CMP(1, SCMP_CMP_EQ
, EPOLL_CTL_MOD
));
1083 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(epoll_ctl
),
1084 SCMP_CMP(1, SCMP_CMP_EQ
, EPOLL_CTL_DEL
));
1092 * Function responsible for setting up the prctl syscall for
1093 * the seccomp filter sandbox.
1095 * NOTE: if multiple filters need to be added, the PR_SECCOMP parameter needs
1096 * to be allowlisted in this function.
1099 sb_prctl(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1104 #ifdef ENABLE_FRAGILE_HARDENING
1105 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(prctl
),
1106 SCMP_CMP(0, SCMP_CMP_EQ
, PR_GET_DUMPABLE
));
1110 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(prctl
),
1111 SCMP_CMP(0, SCMP_CMP_EQ
, PR_SET_PTRACER
));
1116 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(prctl
),
1117 SCMP_CMP(0, SCMP_CMP_EQ
, PR_SET_DUMPABLE
));
1125 * Function responsible for setting up the mprotect syscall for
1126 * the seccomp filter sandbox.
1128 * NOTE: does not NEED to be here.. currently only occurs before filter; will
1129 * keep just in case for the future.
1132 sb_mprotect(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1137 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mprotect
),
1138 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
));
1142 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mprotect
),
1143 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_NONE
));
1151 * Function responsible for setting up the rt_sigprocmask syscall for
1152 * the seccomp filter sandbox.
1155 sb_rt_sigprocmask(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1160 #ifdef ENABLE_FRAGILE_HARDENING
1161 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rt_sigprocmask
),
1162 SCMP_CMP(0, SCMP_CMP_EQ
, SIG_BLOCK
));
1167 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rt_sigprocmask
),
1168 SCMP_CMP(0, SCMP_CMP_EQ
, SIG_UNBLOCK
));
1172 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rt_sigprocmask
),
1173 SCMP_CMP(0, SCMP_CMP_EQ
, SIG_SETMASK
));
1181 * Function responsible for setting up the flock syscall for
1182 * the seccomp filter sandbox.
1184 * NOTE: does not need to be here, occurs before filter is applied.
1187 sb_flock(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1192 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(flock
),
1193 SCMP_CMP(1, SCMP_CMP_EQ
, LOCK_EX
|LOCK_NB
));
1197 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(flock
),
1198 SCMP_CMP(1, SCMP_CMP_EQ
, LOCK_UN
));
1206 * Function responsible for setting up the futex syscall for
1207 * the seccomp filter sandbox.
1210 sb_futex(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1216 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(futex
),
1217 SCMP_CMP(1, SCMP_CMP_EQ
,
1218 FUTEX_WAIT_BITSET_PRIVATE
|FUTEX_CLOCK_REALTIME
));
1222 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(futex
),
1223 SCMP_CMP(1, SCMP_CMP_EQ
, FUTEX_WAKE_PRIVATE
));
1227 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(futex
),
1228 SCMP_CMP(1, SCMP_CMP_EQ
, FUTEX_WAIT_PRIVATE
));
1236 * Function responsible for setting up the mremap syscall for
1237 * the seccomp filter sandbox.
1239 * NOTE: so far only occurs before filter is applied.
1242 sb_mremap(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1247 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mremap
),
1248 SCMP_CMP(3, SCMP_CMP_EQ
, MREMAP_MAYMOVE
));
1257 * Function responsible for setting up the stat64 syscall for
1258 * the seccomp filter sandbox.
1261 sb_stat64(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1264 sandbox_cfg_t
*elem
= NULL
;
1266 // for each dynamic parameter filters
1267 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
1268 smp_param_t
*param
= elem
->param
;
1270 if (param
!= NULL
&& param
->prot
== 1 && (param
->syscall
== SCMP_SYS(open
)
1271 || param
->syscall
== SCMP_SYS(stat64
))) {
1272 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(stat64
),
1273 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
));
1275 log_err(LD_BUG
,"(Sandbox) failed to add stat64 syscall, received "
1276 "libseccomp error %d", rc
);
1284 #endif /* defined(__NR_stat64) */
1287 sb_kill(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1291 /* Allow killing anything with signal 0 -- it isn't really a kill. */
1292 return seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(kill
),
1293 SCMP_CMP(1, SCMP_CMP_EQ
, 0));
1296 #endif /* defined(__NR_kill) */
1300 * Array of function pointers responsible for filtering different syscalls at
1301 * a parameter level.
1303 static sandbox_filter_func_t filter_func
[] = {
1322 #ifdef ENABLE_FRAGILE_HARDENING
1343 #ifdef HAVE_KIST_SUPPORT
1350 * Return the interned (and hopefully sandbox-permitted) string equal
1353 * Return NULL if `str` is NULL, or `str` is not an interned string.
1356 sandbox_intern_string(const char *str
)
1358 const char *interned
= sandbox_get_interned_string(str
);
1360 if (sandbox_active
&& str
!= NULL
&& interned
== NULL
) {
1361 log_warn(LD_BUG
, "No interned sandbox parameter found for %s", str
);
1364 return interned
? interned
: str
;
1368 * Return true if the sandbox is running and we are missing an interned string
1372 sandbox_interned_string_is_missing(const char *str
)
1374 return sandbox_active
&& sandbox_get_interned_string(str
) == NULL
;
1378 * Try to find and return the interned string equal to @a str.
1380 * If there is no such string, return NULL.
1383 sandbox_get_interned_string(const char *str
)
1385 sandbox_cfg_t
*elem
;
1390 for (elem
= filter_dynamic
; elem
!= NULL
; elem
= elem
->next
) {
1391 smp_param_t
*param
= elem
->param
;
1394 if (!strcmp(str
, (char*)(param
->value
))) {
1395 return (char*)param
->value
;
1397 if (param
->value2
&& !strcmp(str
, (char*)param
->value2
)) {
1398 return (char*)param
->value2
;
1408 prot_strings_helper(strmap_t
*locations
,
1409 char **pr_mem_next_p
,
1410 size_t *pr_mem_left_p
,
1420 param_val
= (char*) *value_p
;
1421 param_size
= strlen(param_val
) + 1;
1422 location
= strmap_get(locations
, param_val
);
1425 // We already interned this string.
1426 tor_free(param_val
);
1427 *value_p
= location
;
1429 } else if (*pr_mem_left_p
>= param_size
) {
1430 // copy to protected
1431 location
= *pr_mem_next_p
;
1432 memcpy(location
, param_val
, param_size
);
1434 // re-point el parameter to protected
1435 tor_free(param_val
);
1436 *value_p
= location
;
1438 strmap_set(locations
, location
, location
); /* good real estate advice */
1440 // move next available protected memory
1441 *pr_mem_next_p
+= param_size
;
1442 *pr_mem_left_p
-= param_size
;
1445 log_err(LD_BUG
,"(Sandbox) insufficient protected memory!");
1451 * Protects all the strings in the sandbox's parameter list configuration. It
1452 * works by calculating the total amount of memory required by the parameter
1453 * list, allocating the memory using mmap, and protecting it from writes with
1457 prot_strings(scmp_filter_ctx ctx
, sandbox_cfg_t
* cfg
)
1460 size_t pr_mem_size
= 0, pr_mem_left
= 0;
1461 char *pr_mem_next
= NULL
, *pr_mem_base
;
1462 sandbox_cfg_t
*el
= NULL
;
1463 strmap_t
*locations
= NULL
;
1465 // get total number of bytes required to mmap. (Overestimate.)
1466 for (el
= cfg
; el
!= NULL
; el
= el
->next
) {
1467 pr_mem_size
+= strlen((char*) el
->param
->value
) + 1;
1468 if (el
->param
->value2
)
1469 pr_mem_size
+= strlen((char*) el
->param
->value2
) + 1;
1472 // allocate protected memory with MALLOC_MP_LIM canary
1473 pr_mem_base
= (char*) mmap(NULL
, MALLOC_MP_LIM
+ pr_mem_size
,
1474 PROT_READ
| PROT_WRITE
, MAP_PRIVATE
| MAP_ANON
, -1, 0);
1475 if (pr_mem_base
== MAP_FAILED
) {
1476 log_err(LD_BUG
,"(Sandbox) failed allocate protected memory! mmap: %s",
1482 pr_mem_next
= pr_mem_base
+ MALLOC_MP_LIM
;
1483 pr_mem_left
= pr_mem_size
;
1485 locations
= strmap_new();
1487 // change el value pointer to protected
1488 for (el
= cfg
; el
!= NULL
; el
= el
->next
) {
1489 if (prot_strings_helper(locations
, &pr_mem_next
, &pr_mem_left
,
1490 &el
->param
->value
) < 0) {
1494 if (prot_strings_helper(locations
, &pr_mem_next
, &pr_mem_left
,
1495 &el
->param
->value2
) < 0) {
1499 el
->param
->prot
= 1;
1502 // protecting from writes
1503 if (mprotect(pr_mem_base
, MALLOC_MP_LIM
+ pr_mem_size
, PROT_READ
)) {
1504 log_err(LD_BUG
,"(Sandbox) failed to protect memory! mprotect: %s",
1511 * Setting sandbox restrictions so the string memory cannot be tampered with
1513 // no mremap of the protected base address
1514 ret
= seccomp_rule_add_1(ctx
, SCMP_ACT_KILL
, SCMP_SYS(mremap
),
1515 SCMP_CMP(0, SCMP_CMP_EQ
, (intptr_t) pr_mem_base
));
1517 log_err(LD_BUG
,"(Sandbox) mremap protected memory filter fail!");
1521 // no munmap of the protected base address
1522 ret
= seccomp_rule_add_1(ctx
, SCMP_ACT_KILL
, SCMP_SYS(munmap
),
1523 SCMP_CMP(0, SCMP_CMP_EQ
, (intptr_t) pr_mem_base
));
1525 log_err(LD_BUG
,"(Sandbox) munmap protected memory filter fail!");
1530 * Allow mprotect with PROT_READ|PROT_WRITE because openssl uses it, but
1531 * never over the memory region used by the protected strings.
1533 * PROT_READ|PROT_WRITE was originally fully allowed in sb_mprotect(), but
1534 * had to be removed due to limitation of libseccomp regarding intervals.
1536 * There is a restriction on how much you can mprotect with R|W up to the
1537 * size of the canary.
1539 ret
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mprotect
),
1540 SCMP_CMP(0, SCMP_CMP_LT
, (intptr_t) pr_mem_base
),
1541 SCMP_CMP(1, SCMP_CMP_LE
, MALLOC_MP_LIM
),
1542 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
));
1544 log_err(LD_BUG
,"(Sandbox) mprotect protected memory filter fail (LT)!");
1548 ret
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mprotect
),
1549 SCMP_CMP(0, SCMP_CMP_GT
, (intptr_t) pr_mem_base
+ pr_mem_size
+
1551 SCMP_CMP(1, SCMP_CMP_LE
, MALLOC_MP_LIM
),
1552 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
));
1554 log_err(LD_BUG
,"(Sandbox) mprotect protected memory filter fail (GT)!");
1559 strmap_free(locations
, NULL
);
1564 * Auxiliary function used in order to allocate a sandbox_cfg_t element and set
1565 * its values according the parameter list. All elements are initialised
1566 * with the 'prot' field set to false, as the pointer is not protected at this
1569 static sandbox_cfg_t
*
1570 new_element2(int syscall
, char *value
, char *value2
)
1572 smp_param_t
*param
= NULL
;
1574 sandbox_cfg_t
*elem
= tor_malloc_zero(sizeof(sandbox_cfg_t
));
1575 param
= elem
->param
= tor_malloc_zero(sizeof(smp_param_t
));
1577 param
->syscall
= syscall
;
1578 param
->value
= value
;
1579 param
->value2
= value2
;
1585 static sandbox_cfg_t
*
1586 new_element(int syscall
, char *value
)
1588 return new_element2(syscall
, value
, NULL
);
1592 #define SCMP_chown SCMP_SYS(chown32)
1594 #define SCMP_chown SCMP_SYS(chown)
1598 #define SCMP_stat SCMP_SYS(stat64)
1600 #define SCMP_stat SCMP_SYS(stat)
1604 sandbox_cfg_allow_stat_filename(sandbox_cfg_t
**cfg
, char *file
)
1606 sandbox_cfg_t
*elem
= NULL
;
1608 elem
= new_element(SCMP_stat
, file
);
1617 sandbox_cfg_allow_open_filename(sandbox_cfg_t
**cfg
, char *file
)
1619 sandbox_cfg_t
*elem
= NULL
;
1621 elem
= new_element(SCMP_SYS(open
), file
);
1630 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t
**cfg
, char *file
)
1632 sandbox_cfg_t
*elem
= NULL
;
1634 elem
= new_element(SCMP_SYS(chmod
), file
);
1643 sandbox_cfg_allow_chown_filename(sandbox_cfg_t
**cfg
, char *file
)
1645 sandbox_cfg_t
*elem
= NULL
;
1647 elem
= new_element(SCMP_chown
, file
);
1656 sandbox_cfg_allow_rename(sandbox_cfg_t
**cfg
, char *file1
, char *file2
)
1658 sandbox_cfg_t
*elem
= NULL
;
1660 elem
= new_element2(SCMP_SYS(rename
), file1
, file2
);
1669 sandbox_cfg_allow_openat_filename(sandbox_cfg_t
**cfg
, char *file
)
1671 sandbox_cfg_t
*elem
= NULL
;
1673 elem
= new_element(SCMP_SYS(openat
), file
);
1682 sandbox_cfg_allow_opendir_dirname(sandbox_cfg_t
**cfg
, char *dir
)
1684 sandbox_cfg_t
*elem
= NULL
;
1686 elem
= new_element(PHONY_OPENDIR_SYSCALL
, dir
);
1695 * Function responsible for going through the parameter syscall filters and
1696 * call each function pointer in the list.
1699 add_param_filter(scmp_filter_ctx ctx
, sandbox_cfg_t
* cfg
)
1705 for (i
= 0; i
< ARRAY_LENGTH(filter_func
); i
++) {
1706 rc
= filter_func
[i
](ctx
, cfg
);
1708 log_err(LD_BUG
,"(Sandbox) failed to add syscall %d, received libseccomp "
1718 * Function responsible of loading the libseccomp syscall filters which do not
1719 * have parameter filtering.
1722 add_noparam_filter(scmp_filter_ctx ctx
)
1727 // add general filters
1728 for (i
= 0; i
< ARRAY_LENGTH(filter_nopar_gen
); i
++) {
1729 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, filter_nopar_gen
[i
]);
1731 log_err(LD_BUG
,"(Sandbox) failed to add syscall index %d (NR=%d), "
1732 "received libseccomp error %d", i
, filter_nopar_gen
[i
], rc
);
1737 if (is_libc_at_least(2, 33)) {
1738 #ifdef __NR_newfstatat
1739 // Libc 2.33 uses this syscall to implement both fstat() and stat().
1741 // The trouble is that to implement fstat(fd, &st), it calls:
1742 // newfstatat(fs, "", &st, AT_EMPTY_PATH)
1743 // We can't detect this usage in particular, because "" is a pointer
1744 // we don't control. And we can't just look for AT_EMPTY_PATH, since
1745 // AT_EMPTY_PATH only has effect when the path string is empty.
1747 // So our only solution seems to be allowing all fstatat calls, which
1748 // means that an attacker can stat() anything on the filesystem. That's
1749 // not a great solution, but I can't find a better one.
1750 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(newfstatat
));
1752 log_err(LD_BUG
,"(Sandbox) failed to add newfstatat() syscall; "
1753 "received libseccomp error %d", rc
);
1763 * Function responsible for setting up and enabling a global syscall filter.
1764 * The function is a prototype developed for stage 1 of sandboxing Tor.
1765 * Returns 0 on success.
1768 install_syscall_filter(sandbox_cfg_t
* cfg
)
1771 scmp_filter_ctx ctx
;
1773 ctx
= seccomp_init(SCMP_ACT_ERRNO(EPERM
));
1775 log_err(LD_BUG
,"(Sandbox) failed to initialise libseccomp context");
1780 // protecting sandbox parameter strings
1781 if ((rc
= prot_strings(ctx
, cfg
))) {
1785 // add parameter filters
1786 if ((rc
= add_param_filter(ctx
, cfg
))) {
1787 log_err(LD_BUG
, "(Sandbox) failed to add param filters!");
1791 // adding filters with no parameters
1792 if ((rc
= add_noparam_filter(ctx
))) {
1793 log_err(LD_BUG
, "(Sandbox) failed to add param filters!");
1797 // loading the seccomp2 filter
1798 if ((rc
= seccomp_load(ctx
))) {
1799 log_err(LD_BUG
, "(Sandbox) failed to load: %d (%s)! "
1800 "Are you sure that your kernel has seccomp2 support? The "
1801 "sandbox won't work without it.", rc
,
1806 // marking the sandbox as active
1810 seccomp_release(ctx
);
1811 return (rc
< 0 ? -rc
: rc
);
1814 #ifdef SYSCALL_NAME_DEBUGGING
1815 #include "lib/sandbox/linux_syscalls.inc"
1817 /** Return a string containing the name of a given syscall (if we know it) */
1819 get_syscall_name(int syscall_num
)
1822 for (i
= 0; SYSCALLS_BY_NUMBER
[i
].syscall_name
; ++i
) {
1823 if (SYSCALLS_BY_NUMBER
[i
].syscall_num
== syscall_num
)
1824 return SYSCALLS_BY_NUMBER
[i
].syscall_name
;
1828 static char syscall_name_buf
[64];
1829 format_dec_number_sigsafe(syscall_num
,
1830 syscall_name_buf
, sizeof(syscall_name_buf
));
1831 return syscall_name_buf
;
1835 /** Return the syscall number from a ucontext_t that we got in a signal
1836 * handler (if we know how to do that). */
1838 get_syscall_from_ucontext(const ucontext_t
*ctx
)
1840 return (int) ctx
->uc_mcontext
.M_SYSCALL
;
1842 #else /* !defined(SYSCALL_NAME_DEBUGGING) */
1844 get_syscall_name(int syscall_num
)
1850 get_syscall_from_ucontext(const ucontext_t
*ctx
)
1855 #endif /* defined(SYSCALL_NAME_DEBUGGING) */
1857 #ifdef USE_BACKTRACE
1858 #define MAX_DEPTH 256
1859 static void *syscall_cb_buf
[MAX_DEPTH
];
1863 * Function called when a SIGSYS is caught by the application. It notifies the
1864 * user that an error has occurred and either terminates or allows the
1865 * application to continue execution, based on the DEBUGGING_CLOSE symbol.
1868 sigsys_debugging(int nr
, siginfo_t
*info
, void *void_context
)
1870 ucontext_t
*ctx
= (ucontext_t
*) (void_context
);
1871 const char *syscall_name
;
1872 #ifdef USE_BACKTRACE
1875 const int *fds
= NULL
;
1880 if (info
->si_code
!= SYS_SECCOMP
)
1886 int syscall
= get_syscall_from_ucontext(ctx
);
1888 #ifdef USE_BACKTRACE
1889 depth
= backtrace(syscall_cb_buf
, MAX_DEPTH
);
1890 /* Clean up the top stack frame so we get the real function
1891 * name for the most recently failing function. */
1892 clean_backtrace(syscall_cb_buf
, depth
, ctx
);
1893 #endif /* defined(USE_BACKTRACE) */
1895 syscall_name
= get_syscall_name(syscall
);
1897 tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
1902 #ifdef USE_BACKTRACE
1903 n_fds
= tor_log_get_sigsafe_err_fds(&fds
);
1904 for (i
=0; i
< n_fds
; ++i
)
1905 backtrace_symbols_fd(syscall_cb_buf
, (int)depth
, fds
[i
]);
1908 #if defined(DEBUGGING_CLOSE)
1909 _exit(1); // exit ok: programming error has led to sandbox failure.
1910 #endif // DEBUGGING_CLOSE
1914 * Function that adds a handler for SIGSYS, which is the signal thrown
1915 * when the application is issuing a syscall which is not allowed. The
1916 * main purpose of this function is to help with debugging by identifying
1917 * filtered syscalls.
1920 install_sigsys_debugging(void)
1922 struct sigaction act
;
1925 memset(&act
, 0, sizeof(act
));
1927 sigaddset(&mask
, SIGSYS
);
1929 act
.sa_sigaction
= &sigsys_debugging
;
1930 act
.sa_flags
= SA_SIGINFO
;
1931 if (sigaction(SIGSYS
, &act
, NULL
) < 0) {
1932 log_err(LD_BUG
,"(Sandbox) Failed to register SIGSYS signal handler");
1936 if (sigprocmask(SIG_UNBLOCK
, &mask
, NULL
)) {
1937 log_err(LD_BUG
,"(Sandbox) Failed call to sigprocmask()");
1945 * Function responsible of registering the sandbox_cfg_t list of parameter
1946 * syscall filters to the existing parameter list. This is used for incipient
1947 * multiple-sandbox support.
1950 register_cfg(sandbox_cfg_t
* cfg
)
1952 sandbox_cfg_t
*elem
= NULL
;
1954 if (filter_dynamic
== NULL
) {
1955 filter_dynamic
= cfg
;
1959 for (elem
= filter_dynamic
; elem
->next
!= NULL
; elem
= elem
->next
)
1967 #endif /* defined(USE_LIBSECCOMP) */
1969 #ifdef USE_LIBSECCOMP
1971 * Initialises the syscall sandbox filter for any linux architecture, taking
1972 * into account various available features for different linux flavours.
1975 initialise_libseccomp_sandbox(sandbox_cfg_t
* cfg
)
1977 /* Prevent glibc from trying to open /dev/tty on fatal error */
1978 setenv("LIBC_FATAL_STDERR_", "1", 1);
1980 if (install_sigsys_debugging())
1983 if (install_syscall_filter(cfg
))
1986 if (register_cfg(cfg
))
1993 sandbox_is_active(void)
1995 return sandbox_active
!= 0;
1997 #endif /* defined(USE_LIBSECCOMP) */
2000 sandbox_cfg_new(void)
2006 sandbox_init(sandbox_cfg_t
*cfg
)
2008 #if defined(USE_LIBSECCOMP)
2009 return initialise_libseccomp_sandbox(cfg
);
2011 #elif defined(__linux__)
2013 log_warn(LD_GENERAL
,
2014 "This version of Tor was built without support for sandboxing. To "
2015 "build with support for sandboxing on Linux, you must have "
2016 "libseccomp and its necessary header files (e.g. seccomp.h).");
2021 log_warn(LD_GENERAL
,
2022 "Currently, sandboxing is only implemented on Linux. The feature "
2023 "is disabled on your platform.");
2025 #endif /* defined(USE_LIBSECCOMP) || ... */
2028 #ifndef USE_LIBSECCOMP
2030 sandbox_cfg_allow_open_filename(sandbox_cfg_t
**cfg
, char *file
)
2032 (void)cfg
; (void)file
;
2037 sandbox_cfg_allow_openat_filename(sandbox_cfg_t
**cfg
, char *file
)
2039 (void)cfg
; (void)file
;
2044 sandbox_cfg_allow_opendir_dirname(sandbox_cfg_t
**cfg
, char *dir
)
2046 (void)cfg
; (void)dir
;
2051 sandbox_cfg_allow_stat_filename(sandbox_cfg_t
**cfg
, char *file
)
2053 (void)cfg
; (void)file
;
2058 sandbox_cfg_allow_chown_filename(sandbox_cfg_t
**cfg
, char *file
)
2060 (void)cfg
; (void)file
;
2065 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t
**cfg
, char *file
)
2067 (void)cfg
; (void)file
;
2072 sandbox_cfg_allow_rename(sandbox_cfg_t
**cfg
, char *file1
, char *file2
)
2074 (void)cfg
; (void)file1
; (void)file2
;
2079 sandbox_is_active(void)
2084 #endif /* !defined(USE_LIBSECCOMP) */