diff options
Diffstat (limited to 'src/common/sandbox.c')
-rw-r--r-- | src/common/sandbox.c | 161 |
1 files changed, 69 insertions, 92 deletions
diff --git a/src/common/sandbox.c b/src/common/sandbox.c index 7f4511db2a..7a4e3ece38 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2016, The Tor Project, Inc. */ + * Copyright (c) 2007-2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -17,10 +17,16 @@ * with the libevent fix. */ #define _LARGEFILE64_SOURCE -#endif +#endif /* !defined(_LARGEFILE64_SOURCE) */ -/** Malloc mprotect limit in bytes. */ -#define MALLOC_MP_LIM 1048576 +/** Malloc mprotect limit in bytes. + * + * 28/06/2017: This value was increased from 16 MB to 20 MB after we introduced + * LZMA support in Tor (0.3.1.1-alpha). We limit our LZMA coder to 16 MB, but + * liblzma have a small overhead that we need to compensate for to avoid being + * killed by the sandbox. + */ +#define MALLOC_MP_LIM (20*1024*1024) #include <stdio.h> #include <string.h> @@ -71,7 +77,7 @@ #define USE_BACKTRACE #define EXPOSE_CLEAN_BACKTRACE #include "backtrace.h" -#endif +#endif /* defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && ... */ #ifdef USE_BACKTRACE #include <execinfo.h> @@ -97,7 +103,7 @@ #define M_SYSCALL arm_r7 -#endif +#endif /* defined(__i386__) || ... */ /**Determines if at least one sandbox is active.*/ static int sandbox_active = 0; @@ -283,37 +289,6 @@ sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return rc; } -#if 0 -/** - * Function responsible for setting up the execve syscall for - * the seccomp filter sandbox. - */ -static int -sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter) -{ - int rc; - sandbox_cfg_t *elem = NULL; - - // for each dynamic parameter filters - for (elem = filter; elem != NULL; elem = elem->next) { - smp_param_t *param = elem->param; - - if (param != NULL && param->prot == 1 && param->syscall - == SCMP_SYS(execve)) { - rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), - SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); - if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add execve syscall, received " - "libseccomp error %d", rc); - return rc; - } - } - } - - return 0; -} -#endif - /** * Function responsible for setting up the time syscall for * the seccomp filter sandbox. @@ -327,7 +302,7 @@ sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(0, SCMP_CMP_EQ, 0)); #else return 0; -#endif +#endif /* defined(__NR_time) */ } /** @@ -346,7 +321,7 @@ sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter) if (rc) { return rc; } -#endif +#endif /* defined(__i386__) */ rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0)); @@ -419,7 +394,7 @@ sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } -#endif +#endif /* defined(__NR_mmap2) */ /** * Function responsible for setting up the open syscall for @@ -474,7 +449,7 @@ sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter) rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod), SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " + log_err(LD_BUG,"(Sandbox) failed to add chmod syscall, received " "libseccomp error %d", rc); return rc; } @@ -499,7 +474,7 @@ sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter) rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown), SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " + log_err(LD_BUG,"(Sandbox) failed to add chown syscall, received " "libseccomp error %d", rc); return rc; } @@ -678,6 +653,25 @@ sb_socketpair(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } +#ifdef HAVE_KIST_SUPPORT + +#include <linux/sockios.h> + +static int +sb_ioctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) +{ + int rc; + (void) filter; + + rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), + SCMP_CMP(1, SCMP_CMP_EQ, SIOCOUTQNSD)); + if (rc) + return rc; + return 0; +} + +#endif /* defined(HAVE_KIST_SUPPORT) */ + /** * Function responsible for setting up the setsockopt syscall for * the seccomp filter sandbox. @@ -718,7 +712,7 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUFFORCE)); if (rc) return rc; -#endif +#endif /* defined(HAVE_SYSTEMD) */ #ifdef IP_TRANSPARENT rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), @@ -726,7 +720,7 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT)); if (rc) return rc; -#endif +#endif /* defined(IP_TRANSPARENT) */ #ifdef IPV6_V6ONLY rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), @@ -734,7 +728,7 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, IPV6_V6ONLY)); if (rc) return rc; -#endif +#endif /* defined(IPV6_V6ONLY) */ return 0; } @@ -767,7 +761,7 @@ sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF)); if (rc) return rc; -#endif +#endif /* defined(HAVE_SYSTEMD) */ #ifdef HAVE_LINUX_NETFILTER_IPV4_H rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), @@ -775,7 +769,7 @@ sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST)); if (rc) return rc; -#endif +#endif /* defined(HAVE_LINUX_NETFILTER_IPV4_H) */ #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), @@ -783,7 +777,16 @@ sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST)); if (rc) return rc; -#endif +#endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */ + +#ifdef HAVE_KIST_SUPPORT +#include <netinet/tcp.h> + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), + SCMP_CMP(1, SCMP_CMP_EQ, SOL_TCP), + SCMP_CMP(2, SCMP_CMP_EQ, TCP_INFO)); + if (rc) + return rc; +#endif /* defined(HAVE_KIST_SUPPORT) */ return 0; } @@ -823,7 +826,7 @@ sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } -#endif +#endif /* defined(__NR_fcntl64) */ /** * Function responsible for setting up the epoll_ctl syscall for @@ -1039,8 +1042,8 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64), SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " - "libseccomp error %d", rc); + log_err(LD_BUG,"(Sandbox) failed to add stat64 syscall, received " + "libseccomp error %d", rc); return rc; } } @@ -1048,7 +1051,7 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } -#endif +#endif /* defined(__NR_stat64) */ /** * Array of function pointers responsible for filtering different syscalls at @@ -1057,9 +1060,6 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) static sandbox_filter_func_t filter_func[] = { sb_rt_sigaction, sb_rt_sigprocmask, -#if 0 - sb_execve, -#endif sb_time, sb_accept4, #ifdef __NR_mmap2 @@ -1088,7 +1088,11 @@ static sandbox_filter_func_t filter_func[] = { sb_socket, sb_setsockopt, sb_getsockopt, - sb_socketpair + sb_socketpair, + +#ifdef HAVE_KIST_SUPPORT + sb_ioctl, +#endif }; const char * @@ -1411,26 +1415,6 @@ sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file) return 0; } -#if 0 -int -sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com) -{ - sandbox_cfg_t *elem = NULL; - - elem = new_element(SCMP_SYS(execve), com); - if (!elem) { - log_err(LD_BUG,"(Sandbox) failed to register parameter!"); - return -1; - } - - elem->next = *cfg; - *cfg = elem; - - return 0; -} - -#endif - /** Cache entry for getaddrinfo results; used when sandboxing is implemented * so that we can consult the cache when the sandbox prevents us from doing * getaddrinfo. @@ -1554,7 +1538,7 @@ sandbox_getaddrinfo(const char *name, const char *servname, return err; } - /* Otherwise, the sanbox is on. If we have an item, yield its cached + /* Otherwise, the sandbox is on. If we have an item, yield its cached result. */ if (item) { *res = item->res; @@ -1686,7 +1670,9 @@ install_syscall_filter(sandbox_cfg_t* cfg) // loading the seccomp2 filter if ((rc = seccomp_load(ctx))) { - log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)!", rc, + log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)! " + "Are you sure that your kernel has seccomp2 support? The " + "sandbox won't work without it.", rc, strerror(-rc)); goto end; } @@ -1754,7 +1740,7 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context) /* Clean up the top stack frame so we get the real function * name for the most recently failing function. */ clean_backtrace(syscall_cb_buf, depth, ctx); -#endif +#endif /* defined(USE_BACKTRACE) */ syscall_name = get_syscall_name(syscall); @@ -1828,7 +1814,7 @@ register_cfg(sandbox_cfg_t* cfg) return 0; } -#endif // USE_LIBSECCOMP +#endif /* defined(USE_LIBSECCOMP) */ #ifdef USE_LIBSECCOMP /** @@ -1858,7 +1844,7 @@ sandbox_is_active(void) { return sandbox_active != 0; } -#endif // USE_LIBSECCOMP +#endif /* defined(USE_LIBSECCOMP) */ sandbox_cfg_t* sandbox_cfg_new(void) @@ -1886,7 +1872,7 @@ sandbox_init(sandbox_cfg_t *cfg) "Currently, sandboxing is only implemented on Linux. The feature " "is disabled on your platform."); return 0; -#endif +#endif /* defined(USE_LIBSECCOMP) || ... */ } #ifndef USE_LIBSECCOMP @@ -1904,15 +1890,6 @@ sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file) return 0; } -#if 0 -int -sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com) -{ - (void)cfg; (void)com; - return 0; -} -#endif - int sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file) { @@ -1951,5 +1928,5 @@ void sandbox_disable_getaddrinfo_cache(void) { } -#endif +#endif /* !defined(USE_LIBSECCOMP) */ |