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-2016, 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
22 /** Malloc mprotect limit in bytes. */
23 #define MALLOC_MP_LIM 1048576
30 #include "container.h"
34 #include "tor_queue.h"
38 #define DEBUGGING_CLOSE
40 #if defined(USE_LIBSECCOMP)
43 #include <sys/syscall.h>
44 #include <sys/types.h>
46 #include <sys/epoll.h>
47 #include <sys/prctl.h>
48 #include <linux/futex.h>
59 #ifdef HAVE_GNU_LIBC_VERSION_H
60 #include <gnu/libc-version.h>
62 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
63 #include <linux/netfilter_ipv4.h>
65 #ifdef HAVE_LINUX_IF_H
68 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
69 #include <linux/netfilter_ipv6/ip6_tables.h>
72 #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
73 defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
75 #define EXPOSE_CLEAN_BACKTRACE
76 #include "backtrace.h"
84 * Linux 32 bit definitions
88 #define REG_SYSCALL REG_EAX
89 #define M_SYSCALL gregs[REG_SYSCALL]
92 * Linux 64 bit definitions
94 #elif defined(__x86_64__)
96 #define REG_SYSCALL REG_RAX
97 #define M_SYSCALL gregs[REG_SYSCALL]
99 #elif defined(__arm__)
101 #define M_SYSCALL arm_r7
105 /**Determines if at least one sandbox is active.*/
106 static int sandbox_active
= 0;
107 /** Holds the parameter list configuration for the sandbox.*/
108 static sandbox_cfg_t
*filter_dynamic
= NULL
;
111 #define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0})
112 #define SCMP_CMP_STR(a,b,c) \
113 ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0})
114 #define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)})
115 /* We use a wrapper here because these masked comparisons seem to be pretty
116 * verbose. Also, it's important to cast to scmp_datum_t before negating the
117 * mask, since otherwise the negation might get applied to a 32 bit value, and
118 * the high bits of the value might get masked out improperly. */
119 #define SCMP_CMP_MASKED(a,b,c) \
120 SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c))
122 /** Variable used for storing all syscall numbers that will be allowed with the
123 * stage 1 general Tor sandbox.
125 static int filter_nopar_gen
[] = {
128 SCMP_SYS(clock_gettime
),
131 SCMP_SYS(epoll_create
),
132 SCMP_SYS(epoll_wait
),
133 #ifdef __NR_epoll_pwait
134 SCMP_SYS(epoll_pwait
),
154 SCMP_SYS(getdents64
),
156 #ifdef __NR_getegid32
160 #ifdef __NR_geteuid32
168 #ifdef __NR_getrlimit
171 SCMP_SYS(gettimeofday
),
184 /* XXXX restrict this in the same ways as mmap2 */
188 #ifdef __NR_nanosleep
194 #ifdef __NR_prlimit64
198 SCMP_SYS(rt_sigreturn
),
199 SCMP_SYS(sched_getaffinity
),
200 #ifdef __NR_sched_yield
201 SCMP_SYS(sched_yield
),
204 SCMP_SYS(set_robust_list
),
205 #ifdef __NR_setrlimit
209 #ifdef __NR_sigaltstack
210 SCMP_SYS(sigaltstack
),
212 #ifdef __NR_sigreturn
220 SCMP_SYS(exit_group
),
225 // getaddrinfo uses this..
229 #ifdef __NR_getrandom
238 * These socket syscalls are not required on x86_64 and not supported with
239 * some libseccomp versions (eg: 1.0.1)
250 SCMP_SYS(getsockname
),
258 /* These macros help avoid the error where the number of filters we add on a
259 * single rule don't match the arg_cnt param. */
260 #define seccomp_rule_add_0(ctx,act,call) \
261 seccomp_rule_add((ctx),(act),(call),0)
262 #define seccomp_rule_add_1(ctx,act,call,f1) \
263 seccomp_rule_add((ctx),(act),(call),1,(f1))
264 #define seccomp_rule_add_2(ctx,act,call,f1,f2) \
265 seccomp_rule_add((ctx),(act),(call),2,(f1),(f2))
266 #define seccomp_rule_add_3(ctx,act,call,f1,f2,f3) \
267 seccomp_rule_add((ctx),(act),(call),3,(f1),(f2),(f3))
268 #define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \
269 seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4))
272 * Function responsible for setting up the rt_sigaction syscall for
273 * the seccomp filter sandbox.
276 sb_rt_sigaction(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
280 int param
[] = { SIGINT
, SIGTERM
, SIGPIPE
, SIGUSR1
, SIGUSR2
, SIGHUP
, SIGCHLD
,
287 for (i
= 0; i
< ARRAY_LENGTH(param
); i
++) {
288 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rt_sigaction
),
289 SCMP_CMP(0, SCMP_CMP_EQ
, param
[i
]));
299 * Function responsible for setting up the execve syscall for
300 * the seccomp filter sandbox.
303 sb_execve(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
306 sandbox_cfg_t
*elem
= NULL
;
308 // for each dynamic parameter filters
309 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
310 smp_param_t
*param
= elem
->param
;
312 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
313 == SCMP_SYS(execve
)) {
314 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(execve
),
315 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
));
317 log_err(LD_BUG
,"(Sandbox) failed to add execve syscall, received "
318 "libseccomp error %d", rc
);
329 * Function responsible for setting up the time syscall for
330 * the seccomp filter sandbox.
333 sb_time(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
337 return seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(time
),
338 SCMP_CMP(0, SCMP_CMP_EQ
, 0));
345 * Function responsible for setting up the accept4 syscall for
346 * the seccomp filter sandbox.
349 sb_accept4(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
355 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socketcall
),
356 SCMP_CMP(0, SCMP_CMP_EQ
, 18));
362 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(accept4
),
363 SCMP_CMP_MASKED(3, SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0));
373 * Function responsible for setting up the mmap2 syscall for
374 * the seccomp filter sandbox.
377 sb_mmap2(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
382 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
383 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
),
384 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
));
389 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
390 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_NONE
),
391 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_ANONYMOUS
|MAP_NORESERVE
));
396 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
397 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
),
398 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_ANONYMOUS
));
403 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
404 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
),
405 SCMP_CMP(3, SCMP_CMP_EQ
,MAP_PRIVATE
|MAP_ANONYMOUS
|MAP_STACK
));
410 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
411 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
),
412 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_FIXED
|MAP_DENYWRITE
));
417 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
418 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
),
419 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_FIXED
|MAP_ANONYMOUS
));
424 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mmap2
),
425 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_EXEC
),
426 SCMP_CMP(3, SCMP_CMP_EQ
, MAP_PRIVATE
|MAP_DENYWRITE
));
435 #ifdef HAVE_GNU_LIBC_VERSION_H
436 #ifdef HAVE_GNU_GET_LIBC_VERSION
437 #define CHECK_LIBC_VERSION
441 /* Return true if we think we're running with a libc that always uses
442 * openat on linux. */
444 libc_uses_openat_for_everything(void)
446 #ifdef CHECK_LIBC_VERSION
447 const char *version
= gnu_get_libc_version();
454 tor_sscanf(version
, "%d.%d", &major
, &minor
);
457 else if (major
== 2 && minor
>= 26)
466 /** Allow a single file to be opened. If <b>use_openat</b> is true,
467 * we're using a libc that remaps all the opens into openats. */
469 allow_file_open(scmp_filter_ctx ctx
, int use_openat
, const char *file
)
472 return seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(openat
),
473 SCMP_CMP(0, SCMP_CMP_EQ
, (unsigned int)AT_FDCWD
),
474 SCMP_CMP_STR(1, SCMP_CMP_EQ
, file
));
476 return seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(open
),
477 SCMP_CMP_STR(0, SCMP_CMP_EQ
, file
));
482 * Function responsible for setting up the open syscall for
483 * the seccomp filter sandbox.
486 sb_open(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
489 sandbox_cfg_t
*elem
= NULL
;
491 int use_openat
= libc_uses_openat_for_everything();
493 // for each dynamic parameter filters
494 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
495 smp_param_t
*param
= elem
->param
;
497 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
499 rc
= allow_file_open(ctx
, use_openat
, param
->value
);
501 log_err(LD_BUG
,"(Sandbox) failed to add open syscall, received "
502 "libseccomp error %d", rc
);
508 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ERRNO(EACCES
), SCMP_SYS(open
),
509 SCMP_CMP_MASKED(1, O_CLOEXEC
|O_NONBLOCK
|O_NOCTTY
|O_NOFOLLOW
,
512 log_err(LD_BUG
,"(Sandbox) failed to add open syscall, received libseccomp "
517 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ERRNO(EACCES
), SCMP_SYS(openat
),
518 SCMP_CMP_MASKED(2, O_CLOEXEC
|O_NONBLOCK
|O_NOCTTY
|O_NOFOLLOW
,
521 log_err(LD_BUG
,"(Sandbox) failed to add openat syscall, received "
522 "libseccomp error %d", rc
);
530 sb_chmod(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
533 sandbox_cfg_t
*elem
= NULL
;
535 // for each dynamic parameter filters
536 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
537 smp_param_t
*param
= elem
->param
;
539 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
540 == SCMP_SYS(chmod
)) {
541 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(chmod
),
542 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
));
544 log_err(LD_BUG
,"(Sandbox) failed to add open syscall, received "
545 "libseccomp error %d", rc
);
555 sb_chown(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
558 sandbox_cfg_t
*elem
= NULL
;
560 // for each dynamic parameter filters
561 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
562 smp_param_t
*param
= elem
->param
;
564 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
565 == SCMP_SYS(chown
)) {
566 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(chown
),
567 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
));
569 log_err(LD_BUG
,"(Sandbox) failed to add open syscall, received "
570 "libseccomp error %d", rc
);
580 sb__sysctl(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
586 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ERRNO(EPERM
), SCMP_SYS(_sysctl
));
588 log_err(LD_BUG
,"(Sandbox) failed to add _sysctl syscall, "
589 "received libseccomp error %d", rc
);
597 * Function responsible for setting up the rename syscall for
598 * the seccomp filter sandbox.
601 sb_rename(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
604 sandbox_cfg_t
*elem
= NULL
;
606 // for each dynamic parameter filters
607 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
608 smp_param_t
*param
= elem
->param
;
610 if (param
!= NULL
&& param
->prot
== 1 &&
611 param
->syscall
== SCMP_SYS(rename
)) {
613 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rename
),
614 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
),
615 SCMP_CMP_STR(1, SCMP_CMP_EQ
, param
->value2
));
617 log_err(LD_BUG
,"(Sandbox) failed to add rename syscall, received "
618 "libseccomp error %d", rc
);
628 * Function responsible for setting up the openat syscall for
629 * the seccomp filter sandbox.
632 sb_openat(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
635 sandbox_cfg_t
*elem
= NULL
;
637 // for each dynamic parameter filters
638 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
639 smp_param_t
*param
= elem
->param
;
641 if (param
!= NULL
&& param
->prot
== 1 && param
->syscall
642 == SCMP_SYS(openat
)) {
643 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(openat
),
644 SCMP_CMP(0, SCMP_CMP_EQ
, AT_FDCWD
),
645 SCMP_CMP_STR(1, SCMP_CMP_EQ
, param
->value
),
646 SCMP_CMP(2, SCMP_CMP_EQ
, O_RDONLY
|O_NONBLOCK
|O_LARGEFILE
|O_DIRECTORY
|
649 log_err(LD_BUG
,"(Sandbox) failed to add openat syscall, received "
650 "libseccomp error %d", rc
);
660 * Function responsible for setting up the socket syscall for
661 * the seccomp filter sandbox.
664 sb_socket(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
671 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
));
676 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
677 SCMP_CMP(0, SCMP_CMP_EQ
, PF_FILE
),
678 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
|SOCK_NONBLOCK
, SOCK_STREAM
));
682 for (i
= 0; i
< 2; ++i
) {
683 const int pf
= i
? PF_INET
: PF_INET6
;
684 for (j
=0; j
< 3; ++j
) {
685 const int type
= (j
== 0) ? SOCK_STREAM
:
687 const int protocol
= (j
== 0) ? IPPROTO_TCP
:
688 (j
== 1) ? IPPROTO_IP
:
690 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
691 SCMP_CMP(0, SCMP_CMP_EQ
, pf
),
692 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
|SOCK_NONBLOCK
, type
),
693 SCMP_CMP(2, SCMP_CMP_EQ
, protocol
));
699 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
700 SCMP_CMP(0, SCMP_CMP_EQ
, PF_UNIX
),
701 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
|SOCK_NONBLOCK
, SOCK_STREAM
),
702 SCMP_CMP(2, SCMP_CMP_EQ
, 0));
706 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
707 SCMP_CMP(0, SCMP_CMP_EQ
, PF_UNIX
),
708 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
|SOCK_NONBLOCK
, SOCK_DGRAM
),
709 SCMP_CMP(2, SCMP_CMP_EQ
, 0));
713 rc
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
),
714 SCMP_CMP(0, SCMP_CMP_EQ
, PF_NETLINK
),
715 SCMP_CMP_MASKED(1, SOCK_CLOEXEC
, SOCK_RAW
),
716 SCMP_CMP(2, SCMP_CMP_EQ
, 0));
724 * Function responsible for setting up the socketpair syscall for
725 * the seccomp filter sandbox.
728 sb_socketpair(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
734 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socketpair
));
739 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socketpair
),
740 SCMP_CMP(0, SCMP_CMP_EQ
, PF_FILE
),
741 SCMP_CMP(1, SCMP_CMP_EQ
, SOCK_STREAM
|SOCK_CLOEXEC
));
749 * Function responsible for setting up the setsockopt syscall for
750 * the seccomp filter sandbox.
753 sb_setsockopt(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
759 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
));
764 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
765 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
766 SCMP_CMP(2, SCMP_CMP_EQ
, SO_REUSEADDR
));
770 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
771 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
772 SCMP_CMP(2, SCMP_CMP_EQ
, SO_SNDBUF
));
776 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
777 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
778 SCMP_CMP(2, SCMP_CMP_EQ
, SO_RCVBUF
));
783 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
784 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
785 SCMP_CMP(2, SCMP_CMP_EQ
, SO_SNDBUFFORCE
));
790 #ifdef IP_TRANSPARENT
791 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
792 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_IP
),
793 SCMP_CMP(2, SCMP_CMP_EQ
, IP_TRANSPARENT
));
799 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
),
800 SCMP_CMP(1, SCMP_CMP_EQ
, IPPROTO_IPV6
),
801 SCMP_CMP(2, SCMP_CMP_EQ
, IPV6_V6ONLY
));
810 * Function responsible for setting up the getsockopt syscall for
811 * the seccomp filter sandbox.
814 sb_getsockopt(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
820 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
));
825 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
826 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
827 SCMP_CMP(2, SCMP_CMP_EQ
, SO_ERROR
));
832 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
833 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_SOCKET
),
834 SCMP_CMP(2, SCMP_CMP_EQ
, SO_SNDBUF
));
839 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
840 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
841 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_IP
),
842 SCMP_CMP(2, SCMP_CMP_EQ
, SO_ORIGINAL_DST
));
847 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
848 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(getsockopt
),
849 SCMP_CMP(1, SCMP_CMP_EQ
, SOL_IPV6
),
850 SCMP_CMP(2, SCMP_CMP_EQ
, IP6T_SO_ORIGINAL_DST
));
860 * Function responsible for setting up the fcntl64 syscall for
861 * the seccomp filter sandbox.
864 sb_fcntl64(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
869 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
),
870 SCMP_CMP(1, SCMP_CMP_EQ
, F_GETFL
));
874 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
),
875 SCMP_CMP(1, SCMP_CMP_EQ
, F_SETFL
),
876 SCMP_CMP(2, SCMP_CMP_EQ
, O_RDWR
|O_NONBLOCK
));
880 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
),
881 SCMP_CMP(1, SCMP_CMP_EQ
, F_GETFD
));
885 rc
= seccomp_rule_add_2(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
),
886 SCMP_CMP(1, SCMP_CMP_EQ
, F_SETFD
),
887 SCMP_CMP(2, SCMP_CMP_EQ
, FD_CLOEXEC
));
896 * Function responsible for setting up the epoll_ctl syscall for
897 * the seccomp filter sandbox.
899 * Note: basically allows everything but will keep for now..
902 sb_epoll_ctl(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
907 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(epoll_ctl
),
908 SCMP_CMP(1, SCMP_CMP_EQ
, EPOLL_CTL_ADD
));
912 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(epoll_ctl
),
913 SCMP_CMP(1, SCMP_CMP_EQ
, EPOLL_CTL_MOD
));
917 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(epoll_ctl
),
918 SCMP_CMP(1, SCMP_CMP_EQ
, EPOLL_CTL_DEL
));
926 * Function responsible for setting up the prctl syscall for
927 * the seccomp filter sandbox.
929 * NOTE: if multiple filters need to be added, the PR_SECCOMP parameter needs
930 * to be whitelisted in this function.
933 sb_prctl(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
938 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(prctl
),
939 SCMP_CMP(0, SCMP_CMP_EQ
, PR_SET_DUMPABLE
));
947 * Function responsible for setting up the mprotect syscall for
948 * the seccomp filter sandbox.
950 * NOTE: does not NEED to be here.. currently only occurs before filter; will
951 * keep just in case for the future.
954 sb_mprotect(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
959 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mprotect
),
960 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
));
964 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mprotect
),
965 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_NONE
));
973 * Function responsible for setting up the rt_sigprocmask syscall for
974 * the seccomp filter sandbox.
977 sb_rt_sigprocmask(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
982 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rt_sigprocmask
),
983 SCMP_CMP(0, SCMP_CMP_EQ
, SIG_UNBLOCK
));
987 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(rt_sigprocmask
),
988 SCMP_CMP(0, SCMP_CMP_EQ
, SIG_SETMASK
));
996 * Function responsible for setting up the flock syscall for
997 * the seccomp filter sandbox.
999 * NOTE: does not need to be here, occurs before filter is applied.
1002 sb_flock(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1007 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(flock
),
1008 SCMP_CMP(1, SCMP_CMP_EQ
, LOCK_EX
|LOCK_NB
));
1012 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(flock
),
1013 SCMP_CMP(1, SCMP_CMP_EQ
, LOCK_UN
));
1021 * Function responsible for setting up the futex syscall for
1022 * the seccomp filter sandbox.
1025 sb_futex(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1031 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(futex
),
1032 SCMP_CMP(1, SCMP_CMP_EQ
,
1033 FUTEX_WAIT_BITSET_PRIVATE
|FUTEX_CLOCK_REALTIME
));
1037 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(futex
),
1038 SCMP_CMP(1, SCMP_CMP_EQ
, FUTEX_WAKE_PRIVATE
));
1042 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(futex
),
1043 SCMP_CMP(1, SCMP_CMP_EQ
, FUTEX_WAIT_PRIVATE
));
1051 * Function responsible for setting up the mremap syscall for
1052 * the seccomp filter sandbox.
1054 * NOTE: so far only occurs before filter is applied.
1057 sb_mremap(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1062 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mremap
),
1063 SCMP_CMP(3, SCMP_CMP_EQ
, MREMAP_MAYMOVE
));
1072 * Function responsible for setting up the stat64 syscall for
1073 * the seccomp filter sandbox.
1076 sb_stat64(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1079 sandbox_cfg_t
*elem
= NULL
;
1081 // for each dynamic parameter filters
1082 for (elem
= filter
; elem
!= NULL
; elem
= elem
->next
) {
1083 smp_param_t
*param
= elem
->param
;
1085 if (param
!= NULL
&& param
->prot
== 1 && (param
->syscall
== SCMP_SYS(open
)
1086 || param
->syscall
== SCMP_SYS(stat64
))) {
1087 rc
= seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(stat64
),
1088 SCMP_CMP_STR(0, SCMP_CMP_EQ
, param
->value
));
1090 log_err(LD_BUG
,"(Sandbox) failed to add open syscall, received "
1091 "libseccomp error %d", rc
);
1102 sb_kill(scmp_filter_ctx ctx
, sandbox_cfg_t
*filter
)
1106 /* Allow killing anything with signal 0 -- it isn't really a kill. */
1107 return seccomp_rule_add_1(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(kill
),
1108 SCMP_CMP(1, SCMP_CMP_EQ
, 0));
1115 * Array of function pointers responsible for filtering different syscalls at
1116 * a parameter level.
1118 static sandbox_filter_func_t filter_func
[] = {
1156 sandbox_intern_string(const char *str
)
1158 sandbox_cfg_t
*elem
;
1163 for (elem
= filter_dynamic
; elem
!= NULL
; elem
= elem
->next
) {
1164 smp_param_t
*param
= elem
->param
;
1167 if (!strcmp(str
, (char*)(param
->value
))) {
1168 return (char*)param
->value
;
1170 if (param
->value2
&& !strcmp(str
, (char*)param
->value2
)) {
1171 return (char*)param
->value2
;
1177 log_warn(LD_BUG
, "No interned sandbox parameter found for %s", str
);
1183 prot_strings_helper(strmap_t
*locations
,
1184 char **pr_mem_next_p
,
1185 size_t *pr_mem_left_p
,
1195 param_val
= (char*) *value_p
;
1196 param_size
= strlen(param_val
) + 1;
1197 location
= strmap_get(locations
, param_val
);
1200 // We already interned this string.
1201 tor_free(param_val
);
1202 *value_p
= location
;
1204 } else if (*pr_mem_left_p
>= param_size
) {
1205 // copy to protected
1206 location
= *pr_mem_next_p
;
1207 memcpy(location
, param_val
, param_size
);
1209 // re-point el parameter to protected
1210 tor_free(param_val
);
1211 *value_p
= location
;
1213 strmap_set(locations
, location
, location
); /* good real estate advice */
1215 // move next available protected memory
1216 *pr_mem_next_p
+= param_size
;
1217 *pr_mem_left_p
-= param_size
;
1220 log_err(LD_BUG
,"(Sandbox) insufficient protected memory!");
1226 * Protects all the strings in the sandbox's parameter list configuration. It
1227 * works by calculating the total amount of memory required by the parameter
1228 * list, allocating the memory using mmap, and protecting it from writes with
1232 prot_strings(scmp_filter_ctx ctx
, sandbox_cfg_t
* cfg
)
1235 size_t pr_mem_size
= 0, pr_mem_left
= 0;
1236 char *pr_mem_next
= NULL
, *pr_mem_base
;
1237 sandbox_cfg_t
*el
= NULL
;
1238 strmap_t
*locations
= NULL
;
1240 // get total number of bytes required to mmap. (Overestimate.)
1241 for (el
= cfg
; el
!= NULL
; el
= el
->next
) {
1242 pr_mem_size
+= strlen((char*) el
->param
->value
) + 1;
1243 if (el
->param
->value2
)
1244 pr_mem_size
+= strlen((char*) el
->param
->value2
) + 1;
1247 // allocate protected memory with MALLOC_MP_LIM canary
1248 pr_mem_base
= (char*) mmap(NULL
, MALLOC_MP_LIM
+ pr_mem_size
,
1249 PROT_READ
| PROT_WRITE
, MAP_PRIVATE
| MAP_ANON
, -1, 0);
1250 if (pr_mem_base
== MAP_FAILED
) {
1251 log_err(LD_BUG
,"(Sandbox) failed allocate protected memory! mmap: %s",
1257 pr_mem_next
= pr_mem_base
+ MALLOC_MP_LIM
;
1258 pr_mem_left
= pr_mem_size
;
1260 locations
= strmap_new();
1262 // change el value pointer to protected
1263 for (el
= cfg
; el
!= NULL
; el
= el
->next
) {
1264 if (prot_strings_helper(locations
, &pr_mem_next
, &pr_mem_left
,
1265 &el
->param
->value
) < 0) {
1269 if (prot_strings_helper(locations
, &pr_mem_next
, &pr_mem_left
,
1270 &el
->param
->value2
) < 0) {
1274 el
->param
->prot
= 1;
1277 // protecting from writes
1278 if (mprotect(pr_mem_base
, MALLOC_MP_LIM
+ pr_mem_size
, PROT_READ
)) {
1279 log_err(LD_BUG
,"(Sandbox) failed to protect memory! mprotect: %s",
1286 * Setting sandbox restrictions so the string memory cannot be tampered with
1288 // no mremap of the protected base address
1289 ret
= seccomp_rule_add_1(ctx
, SCMP_ACT_KILL
, SCMP_SYS(mremap
),
1290 SCMP_CMP(0, SCMP_CMP_EQ
, (intptr_t) pr_mem_base
));
1292 log_err(LD_BUG
,"(Sandbox) mremap protected memory filter fail!");
1296 // no munmap of the protected base address
1297 ret
= seccomp_rule_add_1(ctx
, SCMP_ACT_KILL
, SCMP_SYS(munmap
),
1298 SCMP_CMP(0, SCMP_CMP_EQ
, (intptr_t) pr_mem_base
));
1300 log_err(LD_BUG
,"(Sandbox) munmap protected memory filter fail!");
1305 * Allow mprotect with PROT_READ|PROT_WRITE because openssl uses it, but
1306 * never over the memory region used by the protected strings.
1308 * PROT_READ|PROT_WRITE was originally fully allowed in sb_mprotect(), but
1309 * had to be removed due to limitation of libseccomp regarding intervals.
1311 * There is a restriction on how much you can mprotect with R|W up to the
1312 * size of the canary.
1314 ret
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mprotect
),
1315 SCMP_CMP(0, SCMP_CMP_LT
, (intptr_t) pr_mem_base
),
1316 SCMP_CMP(1, SCMP_CMP_LE
, MALLOC_MP_LIM
),
1317 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
));
1319 log_err(LD_BUG
,"(Sandbox) mprotect protected memory filter fail (LT)!");
1323 ret
= seccomp_rule_add_3(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(mprotect
),
1324 SCMP_CMP(0, SCMP_CMP_GT
, (intptr_t) pr_mem_base
+ pr_mem_size
+
1326 SCMP_CMP(1, SCMP_CMP_LE
, MALLOC_MP_LIM
),
1327 SCMP_CMP(2, SCMP_CMP_EQ
, PROT_READ
|PROT_WRITE
));
1329 log_err(LD_BUG
,"(Sandbox) mprotect protected memory filter fail (GT)!");
1334 strmap_free(locations
, NULL
);
1339 * Auxiliary function used in order to allocate a sandbox_cfg_t element and set
1340 * its values according the parameter list. All elements are initialised
1341 * with the 'prot' field set to false, as the pointer is not protected at this
1344 static sandbox_cfg_t
*
1345 new_element2(int syscall
, char *value
, char *value2
)
1347 smp_param_t
*param
= NULL
;
1349 sandbox_cfg_t
*elem
= tor_malloc_zero(sizeof(sandbox_cfg_t
));
1350 param
= elem
->param
= tor_malloc_zero(sizeof(smp_param_t
));
1352 param
->syscall
= syscall
;
1353 param
->value
= value
;
1354 param
->value2
= value2
;
1360 static sandbox_cfg_t
*
1361 new_element(int syscall
, char *value
)
1363 return new_element2(syscall
, value
, NULL
);
1367 #define SCMP_stat SCMP_SYS(stat64)
1369 #define SCMP_stat SCMP_SYS(stat)
1373 sandbox_cfg_allow_stat_filename(sandbox_cfg_t
**cfg
, char *file
)
1375 sandbox_cfg_t
*elem
= NULL
;
1377 elem
= new_element(SCMP_stat
, file
);
1379 log_err(LD_BUG
,"(Sandbox) failed to register parameter!");
1390 sandbox_cfg_allow_open_filename(sandbox_cfg_t
**cfg
, char *file
)
1392 sandbox_cfg_t
*elem
= NULL
;
1394 elem
= new_element(SCMP_SYS(open
), file
);
1396 log_err(LD_BUG
,"(Sandbox) failed to register parameter!");
1407 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t
**cfg
, char *file
)
1409 sandbox_cfg_t
*elem
= NULL
;
1411 elem
= new_element(SCMP_SYS(chmod
), file
);
1413 log_err(LD_BUG
,"(Sandbox) failed to register parameter!");
1424 sandbox_cfg_allow_chown_filename(sandbox_cfg_t
**cfg
, char *file
)
1426 sandbox_cfg_t
*elem
= NULL
;
1428 elem
= new_element(SCMP_SYS(chown
), file
);
1430 log_err(LD_BUG
,"(Sandbox) failed to register parameter!");
1441 sandbox_cfg_allow_rename(sandbox_cfg_t
**cfg
, char *file1
, char *file2
)
1443 sandbox_cfg_t
*elem
= NULL
;
1445 elem
= new_element2(SCMP_SYS(rename
), file1
, file2
);
1448 log_err(LD_BUG
,"(Sandbox) failed to register parameter!");
1459 sandbox_cfg_allow_openat_filename(sandbox_cfg_t
**cfg
, char *file
)
1461 sandbox_cfg_t
*elem
= NULL
;
1463 elem
= new_element(SCMP_SYS(openat
), file
);
1465 log_err(LD_BUG
,"(Sandbox) failed to register parameter!");
1477 sandbox_cfg_allow_execve(sandbox_cfg_t
**cfg
, const char *com
)
1479 sandbox_cfg_t
*elem
= NULL
;
1481 elem
= new_element(SCMP_SYS(execve
), com
);
1483 log_err(LD_BUG
,"(Sandbox) failed to register parameter!");
1495 /** Cache entry for getaddrinfo results; used when sandboxing is implemented
1496 * so that we can consult the cache when the sandbox prevents us from doing
1499 * We support only a limited range of getaddrinfo calls, where servname is null
1500 * and hints contains only socktype=SOCK_STREAM, family in INET,INET6,UNSPEC.
1502 typedef struct cached_getaddrinfo_item_t
{
1503 HT_ENTRY(cached_getaddrinfo_item_t
) node
;
1506 /** set if no error; otherwise NULL */
1507 struct addrinfo
*res
;
1508 /** 0 for no error; otherwise an EAI_* value */
1510 } cached_getaddrinfo_item_t
;
1513 cached_getaddrinfo_item_hash(const cached_getaddrinfo_item_t
*item
)
1515 return (unsigned)siphash24g(item
->name
, strlen(item
->name
)) + item
->family
;
1519 cached_getaddrinfo_items_eq(const cached_getaddrinfo_item_t
*a
,
1520 const cached_getaddrinfo_item_t
*b
)
1522 return (a
->family
== b
->family
) && 0 == strcmp(a
->name
, b
->name
);
1526 cached_getaddrinfo_item_free(cached_getaddrinfo_item_t
*item
)
1531 tor_free(item
->name
);
1533 freeaddrinfo(item
->res
);
1537 static HT_HEAD(getaddrinfo_cache
, cached_getaddrinfo_item_t
)
1538 getaddrinfo_cache
= HT_INITIALIZER();
1540 HT_PROTOTYPE(getaddrinfo_cache
, cached_getaddrinfo_item_t
, node
,
1541 cached_getaddrinfo_item_hash
,
1542 cached_getaddrinfo_items_eq
)
1543 HT_GENERATE2(getaddrinfo_cache
, cached_getaddrinfo_item_t
, node
,
1544 cached_getaddrinfo_item_hash
,
1545 cached_getaddrinfo_items_eq
,
1546 0.6, tor_reallocarray_
, tor_free_
)
1548 /** If true, don't try to cache getaddrinfo results. */
1549 static int sandbox_getaddrinfo_cache_disabled
= 0;
1551 /** Tell the sandbox layer not to try to cache getaddrinfo results. Used as in
1552 * tor-resolve, when we have no intention of initializing crypto or of
1553 * installing the sandbox.*/
1555 sandbox_disable_getaddrinfo_cache(void)
1557 sandbox_getaddrinfo_cache_disabled
= 1;
1561 sandbox_freeaddrinfo(struct addrinfo
*ai
)
1563 if (sandbox_getaddrinfo_cache_disabled
)
1568 sandbox_getaddrinfo(const char *name
, const char *servname
,
1569 const struct addrinfo
*hints
,
1570 struct addrinfo
**res
)
1573 struct cached_getaddrinfo_item_t search
, *item
;
1575 if (sandbox_getaddrinfo_cache_disabled
) {
1576 return getaddrinfo(name
, NULL
, hints
, res
);
1579 if (servname
!= NULL
) {
1580 log_warn(LD_BUG
, "called with non-NULL servname");
1584 log_warn(LD_BUG
, "called with NULL name");
1590 memset(&search
, 0, sizeof(search
));
1591 search
.name
= (char *) name
;
1592 search
.family
= hints
? hints
->ai_family
: AF_UNSPEC
;
1593 item
= HT_FIND(getaddrinfo_cache
, &getaddrinfo_cache
, &search
);
1595 if (! sandbox_is_active()) {
1596 /* If the sandbox is not turned on yet, then getaddrinfo and store the
1599 err
= getaddrinfo(name
, NULL
, hints
, res
);
1600 log_info(LD_NET
,"(Sandbox) getaddrinfo %s.", err
? "failed" : "succeeded");
1603 item
= tor_malloc_zero(sizeof(*item
));
1604 item
->name
= tor_strdup(name
);
1605 item
->family
= hints
? hints
->ai_family
: AF_UNSPEC
;
1606 HT_INSERT(getaddrinfo_cache
, &getaddrinfo_cache
, item
);
1610 freeaddrinfo(item
->res
);
1618 /* Otherwise, the sanbox is on. If we have an item, yield its cached
1625 /* getting here means something went wrong */
1626 log_err(LD_BUG
,"(Sandbox) failed to get address %s!", name
);
1631 sandbox_add_addrinfo(const char *name
)
1633 struct addrinfo
*res
;
1634 struct addrinfo hints
;
1636 static const int families
[] = { AF_INET
, AF_INET6
, AF_UNSPEC
};
1638 memset(&hints
, 0, sizeof(hints
));
1639 hints
.ai_socktype
= SOCK_STREAM
;
1640 for (i
= 0; i
< 3; ++i
) {
1641 hints
.ai_family
= families
[i
];
1644 (void) sandbox_getaddrinfo(name
, NULL
, &hints
, &res
);
1646 sandbox_freeaddrinfo(res
);
1653 sandbox_free_getaddrinfo_cache(void)
1655 cached_getaddrinfo_item_t
**next
, **item
, *this;
1657 for (item
= HT_START(getaddrinfo_cache
, &getaddrinfo_cache
);
1661 next
= HT_NEXT_RMV(getaddrinfo_cache
, &getaddrinfo_cache
, item
);
1662 cached_getaddrinfo_item_free(this);
1665 HT_CLEAR(getaddrinfo_cache
, &getaddrinfo_cache
);
1669 * Function responsible for going through the parameter syscall filters and
1670 * call each function pointer in the list.
1673 add_param_filter(scmp_filter_ctx ctx
, sandbox_cfg_t
* cfg
)
1679 for (i
= 0; i
< ARRAY_LENGTH(filter_func
); i
++) {
1680 rc
= filter_func
[i
](ctx
, cfg
);
1682 log_err(LD_BUG
,"(Sandbox) failed to add syscall %d, received libseccomp "
1692 * Function responsible of loading the libseccomp syscall filters which do not
1693 * have parameter filtering.
1696 add_noparam_filter(scmp_filter_ctx ctx
)
1701 // add general filters
1702 for (i
= 0; i
< ARRAY_LENGTH(filter_nopar_gen
); i
++) {
1703 rc
= seccomp_rule_add_0(ctx
, SCMP_ACT_ALLOW
, filter_nopar_gen
[i
]);
1705 log_err(LD_BUG
,"(Sandbox) failed to add syscall index %d (NR=%d), "
1706 "received libseccomp error %d", i
, filter_nopar_gen
[i
], rc
);
1715 * Function responsible for setting up and enabling a global syscall filter.
1716 * The function is a prototype developed for stage 1 of sandboxing Tor.
1717 * Returns 0 on success.
1720 install_syscall_filter(sandbox_cfg_t
* cfg
)
1723 scmp_filter_ctx ctx
;
1725 ctx
= seccomp_init(SCMP_ACT_TRAP
);
1727 log_err(LD_BUG
,"(Sandbox) failed to initialise libseccomp context");
1732 // protectign sandbox parameter strings
1733 if ((rc
= prot_strings(ctx
, cfg
))) {
1737 // add parameter filters
1738 if ((rc
= add_param_filter(ctx
, cfg
))) {
1739 log_err(LD_BUG
, "(Sandbox) failed to add param filters!");
1743 // adding filters with no parameters
1744 if ((rc
= add_noparam_filter(ctx
))) {
1745 log_err(LD_BUG
, "(Sandbox) failed to add param filters!");
1749 // loading the seccomp2 filter
1750 if ((rc
= seccomp_load(ctx
))) {
1751 log_err(LD_BUG
, "(Sandbox) failed to load: %d (%s)!", rc
,
1756 // marking the sandbox as active
1760 seccomp_release(ctx
);
1761 return (rc
< 0 ? -rc
: rc
);
1764 #include "linux_syscalls.inc"
1766 get_syscall_name(int syscall_num
)
1769 for (i
= 0; SYSCALLS_BY_NUMBER
[i
].syscall_name
; ++i
) {
1770 if (SYSCALLS_BY_NUMBER
[i
].syscall_num
== syscall_num
)
1771 return SYSCALLS_BY_NUMBER
[i
].syscall_name
;
1775 static char syscall_name_buf
[64];
1776 format_dec_number_sigsafe(syscall_num
,
1777 syscall_name_buf
, sizeof(syscall_name_buf
));
1778 return syscall_name_buf
;
1782 #ifdef USE_BACKTRACE
1783 #define MAX_DEPTH 256
1784 static void *syscall_cb_buf
[MAX_DEPTH
];
1788 * Function called when a SIGSYS is caught by the application. It notifies the
1789 * user that an error has occurred and either terminates or allows the
1790 * application to continue execution, based on the DEBUGGING_CLOSE symbol.
1793 sigsys_debugging(int nr
, siginfo_t
*info
, void *void_context
)
1795 ucontext_t
*ctx
= (ucontext_t
*) (void_context
);
1796 const char *syscall_name
;
1798 #ifdef USE_BACKTRACE
1801 const int *fds
= NULL
;
1806 if (info
->si_code
!= SYS_SECCOMP
)
1812 syscall
= (int) ctx
->uc_mcontext
.M_SYSCALL
;
1814 #ifdef USE_BACKTRACE
1815 depth
= backtrace(syscall_cb_buf
, MAX_DEPTH
);
1816 /* Clean up the top stack frame so we get the real function
1817 * name for the most recently failing function. */
1818 clean_backtrace(syscall_cb_buf
, depth
, ctx
);
1821 syscall_name
= get_syscall_name(syscall
);
1823 tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
1828 #ifdef USE_BACKTRACE
1829 n_fds
= tor_log_get_sigsafe_err_fds(&fds
);
1830 for (i
=0; i
< n_fds
; ++i
)
1831 backtrace_symbols_fd(syscall_cb_buf
, (int)depth
, fds
[i
]);
1834 #if defined(DEBUGGING_CLOSE)
1836 #endif // DEBUGGING_CLOSE
1840 * Function that adds a handler for SIGSYS, which is the signal thrown
1841 * when the application is issuing a syscall which is not allowed. The
1842 * main purpose of this function is to help with debugging by identifying
1843 * filtered syscalls.
1846 install_sigsys_debugging(void)
1848 struct sigaction act
;
1851 memset(&act
, 0, sizeof(act
));
1853 sigaddset(&mask
, SIGSYS
);
1855 act
.sa_sigaction
= &sigsys_debugging
;
1856 act
.sa_flags
= SA_SIGINFO
;
1857 if (sigaction(SIGSYS
, &act
, NULL
) < 0) {
1858 log_err(LD_BUG
,"(Sandbox) Failed to register SIGSYS signal handler");
1862 if (sigprocmask(SIG_UNBLOCK
, &mask
, NULL
)) {
1863 log_err(LD_BUG
,"(Sandbox) Failed call to sigprocmask()");
1871 * Function responsible of registering the sandbox_cfg_t list of parameter
1872 * syscall filters to the existing parameter list. This is used for incipient
1873 * multiple-sandbox support.
1876 register_cfg(sandbox_cfg_t
* cfg
)
1878 sandbox_cfg_t
*elem
= NULL
;
1880 if (filter_dynamic
== NULL
) {
1881 filter_dynamic
= cfg
;
1885 for (elem
= filter_dynamic
; elem
->next
!= NULL
; elem
= elem
->next
)
1893 #endif // USE_LIBSECCOMP
1895 #ifdef USE_LIBSECCOMP
1897 * Initialises the syscall sandbox filter for any linux architecture, taking
1898 * into account various available features for different linux flavours.
1901 initialise_libseccomp_sandbox(sandbox_cfg_t
* cfg
)
1903 /* Prevent glibc from trying to open /dev/tty on fatal error */
1904 setenv("LIBC_FATAL_STDERR_", "1", 1);
1906 if (install_sigsys_debugging())
1909 if (install_syscall_filter(cfg
))
1912 if (register_cfg(cfg
))
1919 sandbox_is_active(void)
1921 return sandbox_active
!= 0;
1923 #endif // USE_LIBSECCOMP
1926 sandbox_cfg_new(void)
1932 sandbox_init(sandbox_cfg_t
*cfg
)
1934 #if defined(USE_LIBSECCOMP)
1935 return initialise_libseccomp_sandbox(cfg
);
1937 #elif defined(__linux__)
1939 log_warn(LD_GENERAL
,
1940 "This version of Tor was built without support for sandboxing. To "
1941 "build with support for sandboxing on Linux, you must have "
1942 "libseccomp and its necessary header files (e.g. seccomp.h).");
1947 log_warn(LD_GENERAL
,
1948 "Currently, sandboxing is only implemented on Linux. The feature "
1949 "is disabled on your platform.");
1954 #ifndef USE_LIBSECCOMP
1956 sandbox_cfg_allow_open_filename(sandbox_cfg_t
**cfg
, char *file
)
1958 (void)cfg
; (void)file
;
1963 sandbox_cfg_allow_openat_filename(sandbox_cfg_t
**cfg
, char *file
)
1965 (void)cfg
; (void)file
;
1971 sandbox_cfg_allow_execve(sandbox_cfg_t
**cfg
, const char *com
)
1973 (void)cfg
; (void)com
;
1979 sandbox_cfg_allow_stat_filename(sandbox_cfg_t
**cfg
, char *file
)
1981 (void)cfg
; (void)file
;
1986 sandbox_cfg_allow_chown_filename(sandbox_cfg_t
**cfg
, char *file
)
1988 (void)cfg
; (void)file
;
1993 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t
**cfg
, char *file
)
1995 (void)cfg
; (void)file
;
2000 sandbox_cfg_allow_rename(sandbox_cfg_t
**cfg
, char *file1
, char *file2
)
2002 (void)cfg
; (void)file1
; (void)file2
;
2007 sandbox_is_active(void)
2013 sandbox_disable_getaddrinfo_cache(void)