summaryrefslogtreecommitdiff
path: root/src/common/sandbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/sandbox.c')
-rw-r--r--src/common/sandbox.c420
1 files changed, 243 insertions, 177 deletions
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index 4ce9aa9209..b1c2a09f14 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-2013, The Tor Project, Inc. */
+ * Copyright (c) 2007-2014, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -33,6 +33,8 @@
#include "util.h"
#include "tor_queue.h"
+#include "ht.h"
+
#define DEBUGGING_CLOSE
#if defined(USE_LIBSECCOMP)
@@ -56,6 +58,16 @@
#include <time.h>
#include <poll.h>
+#ifdef HAVE_LINUX_NETFILTER_IPV4_H
+#include <linux/netfilter_ipv4.h>
+#endif
+#ifdef HAVE_LINUX_IF_H
+#include <linux/if.h>
+#endif
+#ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#endif
+
#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
#define USE_BACKTRACE
@@ -67,15 +79,37 @@
#include <execinfo.h>
#endif
+/**
+ * Linux 32 bit definitions
+ */
+#if defined(__i386__)
+
+#define REG_SYSCALL REG_EAX
+#define M_SYSCALL gregs[REG_SYSCALL]
+
+/**
+ * Linux 64 bit definitions
+ */
+#elif defined(__x86_64__)
+
+#define REG_SYSCALL REG_RAX
+#define M_SYSCALL gregs[REG_SYSCALL]
+
+#elif defined(__arm__)
+
+#define M_SYSCALL arm_r7
+
+#endif
+
/**Determines if at least one sandbox is active.*/
static int sandbox_active = 0;
/** Holds the parameter list configuration for the sandbox.*/
static sandbox_cfg_t *filter_dynamic = NULL;
-/** Holds a list of pre-recorded results from getaddrinfo().*/
-static sb_addr_info_t *sb_addr_info = NULL;
#undef SCMP_CMP
#define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0})
+#define SCMP_CMP_STR(a,b,c) \
+ ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0})
#define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)})
/* We use a wrapper here because these masked comparisons seem to be pretty
* verbose. Also, it's important to cast to scmp_datum_t before negating the
@@ -113,8 +147,11 @@ static int filter_nopar_gen[] = {
#ifdef __NR_getgid32
SCMP_SYS(getgid32),
#endif
+#ifdef __NR_getrlimit
SCMP_SYS(getrlimit),
+#endif
SCMP_SYS(gettimeofday),
+ SCMP_SYS(gettid),
SCMP_SYS(getuid),
#ifdef __NR_getuid32
SCMP_SYS(getuid32),
@@ -125,10 +162,14 @@ static int filter_nopar_gen[] = {
#endif
SCMP_SYS(mkdir),
SCMP_SYS(mlockall),
+#ifdef __NR_mmap
+ /* XXXX restrict this in the same ways as mmap2 */
SCMP_SYS(mmap),
+#endif
SCMP_SYS(munmap),
SCMP_SYS(read),
SCMP_SYS(rt_sigreturn),
+ SCMP_SYS(sched_getaffinity),
SCMP_SYS(set_robust_list),
#ifdef __NR_sigreturn
SCMP_SYS(sigreturn),
@@ -157,6 +198,7 @@ static int filter_nopar_gen[] = {
// socket syscalls
SCMP_SYS(bind),
+ SCMP_SYS(listen),
SCMP_SYS(connect),
SCMP_SYS(getsockname),
SCMP_SYS(recvmsg),
@@ -204,6 +246,7 @@ 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.
@@ -221,7 +264,7 @@ sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
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(0, SCMP_CMP_EQ, param->value));
+ 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);
@@ -232,6 +275,7 @@ sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return 0;
}
+#endif
/**
* Function responsible for setting up the time syscall for
@@ -241,8 +285,12 @@ static int
sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
{
(void) filter;
+#ifdef __NR_time
return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time),
SCMP_CMP(0, SCMP_CMP_EQ, 0));
+#else
+ return 0;
+#endif
}
/**
@@ -353,7 +401,7 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
if (param != NULL && param->prot == 1 && param->syscall
== SCMP_SYS(open)) {
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),
- SCMP_CMP(0, SCMP_CMP_EQ, param->value));
+ 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);
@@ -408,8 +456,8 @@ sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
param->syscall == SCMP_SYS(rename)) {
rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename),
- SCMP_CMP(0, SCMP_CMP_EQ, param->value),
- SCMP_CMP(1, SCMP_CMP_EQ, param->value2));
+ SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value),
+ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add rename syscall, received "
"libseccomp error %d", rc);
@@ -439,7 +487,7 @@ sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
== SCMP_SYS(openat)) {
rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
SCMP_CMP(0, SCMP_CMP_EQ, AT_FDCWD),
- SCMP_CMP(1, SCMP_CMP_EQ, param->value),
+ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
O_CLOEXEC));
if (rc != 0) {
@@ -551,6 +599,18 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
if (rc)
return rc;
+ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
+ SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
+ SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
+ if (rc)
+ return rc;
+
+ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
+ SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
+ SCMP_CMP(2, SCMP_CMP_EQ, SO_RCVBUF));
+ if (rc)
+ return rc;
+
#ifdef IP_TRANSPARENT
rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
@@ -584,6 +644,22 @@ sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
if (rc)
return rc;
+#ifdef HAVE_LINUX_NETFILTER_IPV4_H
+ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
+ SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
+ SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST));
+ if (rc)
+ return rc;
+#endif
+
+#ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
+ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
+ SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6),
+ SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST));
+ if (rc)
+ return rc;
+#endif
+
return 0;
}
@@ -836,7 +912,7 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
|| param->syscall == SCMP_SYS(stat64))) {
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64),
- SCMP_CMP(0, SCMP_CMP_EQ, param->value));
+ 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);
@@ -856,7 +932,9 @@ 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
@@ -917,7 +995,7 @@ static int
prot_strings_helper(strmap_t *locations,
char **pr_mem_next_p,
size_t *pr_mem_left_p,
- intptr_t *value_p)
+ char **value_p)
{
char *param_val;
size_t param_size;
@@ -933,7 +1011,7 @@ prot_strings_helper(strmap_t *locations,
if (location) {
// We already interned this string.
tor_free(param_val);
- *value_p = (intptr_t) location;
+ *value_p = location;
return 0;
} else if (*pr_mem_left_p >= param_size) {
// copy to protected
@@ -942,7 +1020,7 @@ prot_strings_helper(strmap_t *locations,
// re-point el parameter to protected
tor_free(param_val);
- *value_p = (intptr_t) location;
+ *value_p = location;
strmap_set(locations, location, location); /* good real estate advice */
@@ -1024,7 +1102,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
if (ret) {
log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!");
- return ret;
+ goto out;
}
// no munmap of the protected base address
@@ -1032,7 +1110,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
if (ret) {
log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!");
- return ret;
+ goto out;
}
/*
@@ -1051,7 +1129,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
if (ret) {
log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!");
- return ret;
+ goto out;
}
ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
@@ -1061,7 +1139,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
if (ret) {
log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!");
- return ret;
+ goto out;
}
out:
@@ -1076,7 +1154,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
* point.
*/
static sandbox_cfg_t*
-new_element2(int syscall, intptr_t value, intptr_t value2)
+new_element2(int syscall, char *value, char *value2)
{
smp_param_t *param = NULL;
@@ -1092,9 +1170,9 @@ new_element2(int syscall, intptr_t value, intptr_t value2)
}
static sandbox_cfg_t*
-new_element(int syscall, intptr_t value)
+new_element(int syscall, char *value)
{
- return new_element2(syscall, value, 0);
+ return new_element2(syscall, value, NULL);
}
#ifdef __NR_stat64
@@ -1108,7 +1186,7 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element(SCMP_stat, (intptr_t)(void*) file);
+ elem = new_element(SCMP_stat, file);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
@@ -1121,33 +1199,11 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
}
int
-sandbox_cfg_allow_stat_filename_array(sandbox_cfg_t **cfg, ...)
-{
- int rc = 0;
- char *fn = NULL;
-
- va_list ap;
- va_start(ap, cfg);
-
- while ((fn = va_arg(ap, char*)) != NULL) {
- rc = sandbox_cfg_allow_stat_filename(cfg, fn);
- if (rc) {
- log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_stat_filename_array fail");
- goto end;
- }
- }
-
- end:
- va_end(ap);
- return 0;
-}
-
-int
sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element(SCMP_SYS(open), (intptr_t)(void *) file);
+ elem = new_element(SCMP_SYS(open), file);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
@@ -1164,9 +1220,7 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element2(SCMP_SYS(rename),
- (intptr_t)(void *) file1,
- (intptr_t)(void *) file2);
+ elem = new_element2(SCMP_SYS(rename), file1, file2);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
@@ -1180,33 +1234,11 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
}
int
-sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...)
-{
- int rc = 0;
- char *fn = NULL;
-
- va_list ap;
- va_start(ap, cfg);
-
- while ((fn = va_arg(ap, char*)) != NULL) {
- rc = sandbox_cfg_allow_open_filename(cfg, fn);
- if (rc) {
- log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_open_filename_array fail");
- goto end;
- }
- }
-
- end:
- va_end(ap);
- return 0;
-}
-
-int
sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element(SCMP_SYS(openat), (intptr_t)(void *) file);
+ elem = new_element(SCMP_SYS(openat), file);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
@@ -1218,34 +1250,13 @@ sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
return 0;
}
-int
-sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...)
-{
- int rc = 0;
- char *fn = NULL;
-
- va_list ap;
- va_start(ap, cfg);
-
- while ((fn = va_arg(ap, char*)) != NULL) {
- rc = sandbox_cfg_allow_openat_filename(cfg, fn);
- if (rc) {
- log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_openat_filename_array fail");
- goto end;
- }
- }
-
- end:
- va_end(ap);
- 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), (intptr_t)(void *) com);
+ elem = new_element(SCMP_SYS(execve), com);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
@@ -1257,27 +1268,71 @@ sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
return 0;
}
-int
-sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...)
+#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.
+ *
+ * We support only a limited range of getaddrinfo calls, where servname is null
+ * and hints contains only socktype=SOCK_STREAM, family in INET,INET6,UNSPEC.
+ */
+typedef struct cached_getaddrinfo_item_t {
+ HT_ENTRY(cached_getaddrinfo_item_t) node;
+ char *name;
+ int family;
+ /** set if no error; otherwise NULL */
+ struct addrinfo *res;
+ /** 0 for no error; otherwise an EAI_* value */
+ int err;
+} cached_getaddrinfo_item_t;
+
+static unsigned
+cached_getaddrinfo_item_hash(const cached_getaddrinfo_item_t *item)
{
- int rc = 0;
- char *fn = NULL;
+ return (unsigned)siphash24g(item->name, strlen(item->name)) + item->family;
+}
- va_list ap;
- va_start(ap, cfg);
+static unsigned
+cached_getaddrinfo_items_eq(const cached_getaddrinfo_item_t *a,
+ const cached_getaddrinfo_item_t *b)
+{
+ return (a->family == b->family) && 0 == strcmp(a->name, b->name);
+}
- while ((fn = va_arg(ap, char*)) != NULL) {
+static void
+cached_getaddrinfo_item_free(cached_getaddrinfo_item_t *item)
+{
+ if (item == NULL)
+ return;
- rc = sandbox_cfg_allow_execve(cfg, fn);
- if (rc) {
- log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_execve_array failed");
- goto end;
- }
- }
+ tor_free(item->name);
+ if (item->res)
+ freeaddrinfo(item->res);
+ tor_free(item);
+}
- end:
- va_end(ap);
- return 0;
+static HT_HEAD(getaddrinfo_cache, cached_getaddrinfo_item_t)
+ getaddrinfo_cache = HT_INITIALIZER();
+
+HT_PROTOTYPE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
+ cached_getaddrinfo_item_hash,
+ cached_getaddrinfo_items_eq);
+HT_GENERATE2(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
+ cached_getaddrinfo_item_hash,
+ cached_getaddrinfo_items_eq,
+ 0.6, tor_reallocarray_, tor_free_)
+
+/** If true, don't try to cache getaddrinfo results. */
+static int sandbox_getaddrinfo_cache_disabled = 0;
+
+/** Tell the sandbox layer not to try to cache getaddrinfo results. Used as in
+ * tor-resolve, when we have no intention of initializing crypto or of
+ * installing the sandbox.*/
+void
+sandbox_disable_getaddrinfo_cache(void)
+{
+ sandbox_getaddrinfo_cache_disabled = 1;
}
int
@@ -1285,68 +1340,99 @@ sandbox_getaddrinfo(const char *name, const char *servname,
const struct addrinfo *hints,
struct addrinfo **res)
{
- sb_addr_info_t *el;
+ int err;
+ struct cached_getaddrinfo_item_t search, *item;
- if (servname != NULL)
- return -1;
+ if (sandbox_getaddrinfo_cache_disabled) {
+ return getaddrinfo(name, NULL, hints, res);
+ }
+
+ if (servname != NULL) {
+ log_warn(LD_BUG, "called with non-NULL servname");
+ return EAI_NONAME;
+ }
+ if (name == NULL) {
+ log_warn(LD_BUG, "called with NULL name");
+ return EAI_NONAME;
+ }
*res = NULL;
- for (el = sb_addr_info; el; el = el->next) {
- if (!strcmp(el->name, name)) {
- *res = tor_malloc(sizeof(struct addrinfo));
+ memset(&search, 0, sizeof(search));
+ search.name = (char *) name;
+ search.family = hints ? hints->ai_family : AF_UNSPEC;
+ item = HT_FIND(getaddrinfo_cache, &getaddrinfo_cache, &search);
- memcpy(*res, el->info, sizeof(struct addrinfo));
- /* XXXX What if there are multiple items in the list? */
- return 0;
+ if (! sandbox_is_active()) {
+ /* If the sandbox is not turned on yet, then getaddrinfo and store the
+ result. */
+
+ err = getaddrinfo(name, NULL, hints, res);
+ log_info(LD_NET,"(Sandbox) getaddrinfo %s.", err ? "failed" : "succeeded");
+
+ if (! item) {
+ item = tor_malloc_zero(sizeof(*item));
+ item->name = tor_strdup(name);
+ item->family = hints ? hints->ai_family : AF_UNSPEC;
+ HT_INSERT(getaddrinfo_cache, &getaddrinfo_cache, item);
}
- }
- if (!sandbox_active) {
- if (getaddrinfo(name, NULL, hints, res)) {
- log_err(LD_BUG,"(Sandbox) getaddrinfo failed!");
- return -1;
+ if (item->res) {
+ freeaddrinfo(item->res);
+ item->res = NULL;
}
+ item->res = *res;
+ item->err = err;
+ return err;
+ }
- return 0;
+ /* Otherwise, the sanbox is on. If we have an item, yield its cached
+ result. */
+ if (item) {
+ *res = item->res;
+ return item->err;
}
- // getting here means something went wrong
+ /* getting here means something went wrong */
log_err(LD_BUG,"(Sandbox) failed to get address %s!", name);
- if (*res) {
- tor_free(*res);
- res = NULL;
- }
- return -1;
+ return EAI_NONAME;
}
int
-sandbox_add_addrinfo(const char* name)
+sandbox_add_addrinfo(const char *name)
{
- int ret;
+ struct addrinfo *res;
struct addrinfo hints;
- sb_addr_info_t *el = NULL;
-
- el = tor_malloc(sizeof(sb_addr_info_t));
+ int i;
+ static const int families[] = { AF_INET, AF_INET6, AF_UNSPEC };
memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
+ for (i = 0; i < 3; ++i) {
+ hints.ai_family = families[i];
- ret = getaddrinfo(name, NULL, &hints, &(el->info));
- if (ret) {
- log_err(LD_BUG,"(Sandbox) failed to getaddrinfo");
- ret = -2;
- tor_free(el);
- goto out;
+ res = NULL;
+ (void) sandbox_getaddrinfo(name, NULL, &hints, &res);
+ if (res)
+ sandbox_freeaddrinfo(res);
}
- el->name = tor_strdup(name);
- el->next = sb_addr_info;
- sb_addr_info = el;
+ return 0;
+}
+
+void
+sandbox_free_getaddrinfo_cache(void)
+{
+ cached_getaddrinfo_item_t **next, **item;
- out:
- return ret;
+ for (item = HT_START(getaddrinfo_cache, &getaddrinfo_cache);
+ item;
+ item = next) {
+ next = HT_NEXT_RMV(getaddrinfo_cache, &getaddrinfo_cache, item);
+ cached_getaddrinfo_item_free(*item);
+ }
+
+ HT_CLEAR(getaddrinfo_cache, &getaddrinfo_cache);
}
/**
@@ -1431,7 +1517,8 @@ install_syscall_filter(sandbox_cfg_t* cfg)
// loading the seccomp2 filter
if ((rc = seccomp_load(ctx))) {
- log_err(LD_BUG, "(Sandbox) failed to load!");
+ log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)!", rc,
+ strerror(-rc));
goto end;
}
@@ -1491,7 +1578,7 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context)
if (!ctx)
return;
- syscall = (int) ctx->uc_mcontext.gregs[REG_SYSCALL];
+ syscall = (int) ctx->uc_mcontext.M_SYSCALL;
#ifdef USE_BACKTRACE
depth = backtrace(syscall_cb_buf, MAX_DEPTH);
@@ -1616,7 +1703,7 @@ sandbox_init(sandbox_cfg_t *cfg)
#elif defined(__linux__)
(void)cfg;
log_warn(LD_GENERAL,
- "This version of Tor was built without support for sanboxing. To "
+ "This version of Tor was built without support for sandboxing. To "
"build with support for sandboxing on Linux, you must have "
"libseccomp and its necessary header files (e.g. seccomp.h).");
return 0;
@@ -1639,39 +1726,20 @@ sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
}
int
-sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...)
-{
- (void)cfg;
- return 0;
-}
-
-int
sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
{
(void)cfg; (void)file;
return 0;
}
-int
-sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...)
-{
- (void)cfg;
- return 0;
-}
-
+#if 0
int
sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
{
(void)cfg; (void)com;
return 0;
}
-
-int
-sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...)
-{
- (void)cfg;
- return 0;
-}
+#endif
int
sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
@@ -1681,13 +1749,6 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
}
int
-sandbox_cfg_allow_stat_filename_array(sandbox_cfg_t **cfg, ...)
-{
- (void)cfg;
- return 0;
-}
-
-int
sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
{
(void)cfg; (void)file1; (void)file2;
@@ -1699,5 +1760,10 @@ sandbox_is_active(void)
{
return 0;
}
+
+void
+sandbox_disable_getaddrinfo_cache(void)
+{
+}
#endif