aboutsummaryrefslogtreecommitdiff
path: root/src/common/sandbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/sandbox.c')
-rw-r--r--src/common/sandbox.c188
1 files changed, 72 insertions, 116 deletions
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index 0a972d496b..e311ffaa86 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>
@@ -74,7 +80,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>
@@ -100,7 +106,12 @@
#define M_SYSCALL arm_r7
-#endif
+#elif defined(__aarch64__) && defined(__LP64__)
+
+#define REG_SYSCALL 8
+#define M_SYSCALL regs[REG_SYSCALL]
+
+#endif /* defined(__i386__) || ... */
/**Determines if at least one sandbox is active.*/
static int sandbox_active = 0;
@@ -293,37 +304,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.
@@ -337,7 +317,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) */
}
/**
@@ -356,7 +336,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));
@@ -429,7 +409,7 @@ sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return 0;
}
-#endif
+#endif /* defined(__NR_mmap2) */
#ifdef HAVE_GNU_LIBC_VERSION_H
#ifdef HAVE_GNU_GET_LIBC_VERSION
@@ -540,7 +520,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;
}
@@ -565,7 +545,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;
}
@@ -744,6 +724,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.
@@ -784,7 +783,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),
@@ -792,7 +791,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),
@@ -800,7 +799,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;
}
@@ -833,7 +832,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),
@@ -841,7 +840,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),
@@ -849,7 +848,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;
}
@@ -889,7 +897,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
@@ -1086,8 +1094,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;
}
}
@@ -1095,7 +1103,7 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return 0;
}
-#endif
+#endif /* defined(__NR_stat64) */
static int
sb_kill(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
@@ -1117,9 +1125,6 @@ sb_kill(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
@@ -1148,6 +1153,9 @@ static sandbox_filter_func_t filter_func[] = {
sb_setsockopt,
sb_getsockopt,
sb_socketpair,
+#ifdef HAVE_KIST_SUPPORT
+ sb_ioctl,
+#endif
sb_kill
};
@@ -1374,10 +1382,6 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
sandbox_cfg_t *elem = NULL;
elem = new_element(SCMP_stat, file);
- if (!elem) {
- log_err(LD_BUG,"(Sandbox) failed to register parameter!");
- return -1;
- }
elem->next = *cfg;
*cfg = elem;
@@ -1391,10 +1395,6 @@ sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
sandbox_cfg_t *elem = NULL;
elem = new_element(SCMP_SYS(open), file);
- if (!elem) {
- log_err(LD_BUG,"(Sandbox) failed to register parameter!");
- return -1;
- }
elem->next = *cfg;
*cfg = elem;
@@ -1408,10 +1408,6 @@ sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
sandbox_cfg_t *elem = NULL;
elem = new_element(SCMP_SYS(chmod), file);
- if (!elem) {
- log_err(LD_BUG,"(Sandbox) failed to register parameter!");
- return -1;
- }
elem->next = *cfg;
*cfg = elem;
@@ -1425,10 +1421,6 @@ sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
sandbox_cfg_t *elem = NULL;
elem = new_element(SCMP_SYS(chown), file);
- if (!elem) {
- log_err(LD_BUG,"(Sandbox) failed to register parameter!");
- return -1;
- }
elem->next = *cfg;
*cfg = elem;
@@ -1443,11 +1435,6 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
elem = new_element2(SCMP_SYS(rename), file1, file2);
- if (!elem) {
- log_err(LD_BUG,"(Sandbox) failed to register parameter!");
- return -1;
- }
-
elem->next = *cfg;
*cfg = elem;
@@ -1460,10 +1447,6 @@ sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
sandbox_cfg_t *elem = NULL;
elem = new_element(SCMP_SYS(openat), file);
- if (!elem) {
- log_err(LD_BUG,"(Sandbox) failed to register parameter!");
- return -1;
- }
elem->next = *cfg;
*cfg = elem;
@@ -1471,26 +1454,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.
@@ -1614,7 +1577,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;
@@ -1747,7 +1710,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;
}
@@ -1815,7 +1780,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);
@@ -1889,7 +1854,7 @@ register_cfg(sandbox_cfg_t* cfg)
return 0;
}
-#endif // USE_LIBSECCOMP
+#endif /* defined(USE_LIBSECCOMP) */
#ifdef USE_LIBSECCOMP
/**
@@ -1919,7 +1884,7 @@ sandbox_is_active(void)
{
return sandbox_active != 0;
}
-#endif // USE_LIBSECCOMP
+#endif /* defined(USE_LIBSECCOMP) */
sandbox_cfg_t*
sandbox_cfg_new(void)
@@ -1947,7 +1912,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
@@ -1965,15 +1930,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)
{
@@ -2012,5 +1968,5 @@ void
sandbox_disable_getaddrinfo_cache(void)
{
}
-#endif
+#endif /* !defined(USE_LIBSECCOMP) */