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.c179
1 files changed, 2 insertions, 177 deletions
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index b41b8f4ba5..9842fd9831 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -37,6 +37,7 @@
#include "lib/err/torerr.h"
#include "lib/log/torlog.h"
#include "lib/cc/torint.h"
+#include "lib/net/resolve.h"
#include "common/util.h"
#include "tor_queue.h"
@@ -1458,183 +1459,6 @@ sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
return 0;
}
-/** 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)
-{
- return (unsigned)siphash24g(item->name, strlen(item->name)) + item->family;
-}
-
-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);
-}
-
-#define cached_getaddrinfo_item_free(item) \
- FREE_AND_NULL(cached_getaddrinfo_item_t, \
- cached_getaddrinfo_item_free_, (item))
-
-static void
-cached_getaddrinfo_item_free_(cached_getaddrinfo_item_t *item)
-{
- if (item == NULL)
- return;
-
- tor_free(item->name);
- if (item->res)
- freeaddrinfo(item->res);
- tor_free(item);
-}
-
-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;
-}
-
-void
-sandbox_freeaddrinfo(struct addrinfo *ai)
-{
- if (sandbox_getaddrinfo_cache_disabled)
- freeaddrinfo(ai);
-}
-
-int
-sandbox_getaddrinfo(const char *name, const char *servname,
- const struct addrinfo *hints,
- struct addrinfo **res)
-{
- int err;
- struct cached_getaddrinfo_item_t search, *item;
-
- 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;
-
- 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);
-
- 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 (item->res) {
- freeaddrinfo(item->res);
- item->res = NULL;
- }
- item->res = *res;
- item->err = err;
- return err;
- }
-
- /* Otherwise, the sandbox 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 */
- log_err(LD_BUG,"(Sandbox) failed to get address %s!", name);
- return EAI_NONAME;
-}
-
-int
-sandbox_add_addrinfo(const char *name)
-{
- struct addrinfo *res;
- struct addrinfo hints;
- int i;
- static const int families[] = { AF_INET, AF_INET6, AF_UNSPEC };
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_STREAM;
- for (i = 0; i < 3; ++i) {
- hints.ai_family = families[i];
-
- res = NULL;
- (void) sandbox_getaddrinfo(name, NULL, &hints, &res);
- if (res)
- sandbox_freeaddrinfo(res);
- }
-
- return 0;
-}
-
-void
-sandbox_free_getaddrinfo_cache(void)
-{
- cached_getaddrinfo_item_t **next, **item, *this;
-
- for (item = HT_START(getaddrinfo_cache, &getaddrinfo_cache);
- item;
- item = next) {
- this = *item;
- next = HT_NEXT_RMV(getaddrinfo_cache, &getaddrinfo_cache, item);
- cached_getaddrinfo_item_free(this);
- }
-
- HT_CLEAR(getaddrinfo_cache, &getaddrinfo_cache);
-}
-
/**
* Function responsible for going through the parameter syscall filters and
* call each function pointer in the list.
@@ -1727,6 +1551,7 @@ install_syscall_filter(sandbox_cfg_t* cfg)
// marking the sandbox as active
sandbox_active = 1;
+ sandbox_make_getaddrinfo_cache_active();
end:
seccomp_release(ctx);