diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-04-16 14:54:39 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-04-16 22:03:09 -0400 |
commit | e6785ee16dce675aa770616bcdbd128d5dfb1132 (patch) | |
tree | 3f5c1b6d827946b36c1aaff010265e9dec432d4f | |
parent | 156eefca454e10440d1070f7500e1708589fc64b (diff) | |
download | tor-e6785ee16dce675aa770616bcdbd128d5dfb1132.tar.gz tor-e6785ee16dce675aa770616bcdbd128d5dfb1132.zip |
Get Libevent's PRNG functioning under the linux sandbox
Libevent uses an arc4random implementation (I know, I know) to
generate DNS transaction IDs and capitalization. But it liked to
initialize it either with opening /dev/urandom (which won't work
under the sandbox if it doesn't use the right pointer), or with
sysctl({CTL_KERN,KERN_RANDOM,RANDOM_UUIC}). To make _that_ work, we
were permitting sysctl unconditionally. That's not such a great
idea.
Instead, we try to initialize the libevent PRNG _before_ installing
the sandbox, and make sysctl always fail with EPERM under the
sandbox.
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/common/compat_libevent.c | 19 | ||||
-rw-r--r-- | src/common/compat_libevent.h | 2 | ||||
-rw-r--r-- | src/common/sandbox.c | 19 | ||||
-rw-r--r-- | src/or/main.c | 10 |
5 files changed, 50 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 6e41041961..6e5331b4c6 100644 --- a/configure.ac +++ b/configure.ac @@ -435,6 +435,7 @@ AC_CHECK_FUNCS([event_get_version \ event_set_log_callback \ evdns_set_outgoing_bind_address \ evutil_secure_rng_set_urandom_device_file \ + evutil_secure_rng_init \ event_base_loopexit]) AC_CHECK_MEMBERS([struct event.min_heap_idx], , , [#include <event.h> diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c index 8525b4a721..74b54bb855 100644 --- a/src/common/compat_libevent.c +++ b/src/common/compat_libevent.c @@ -13,6 +13,8 @@ #include "compat.h" #include "compat_libevent.h" +#include "crypto.h" + #include "util.h" #include "torlog.h" @@ -626,6 +628,23 @@ tor_add_bufferevent_to_rate_limit_group(struct bufferevent *bev, } #endif +int +tor_init_libevent_rng(void) +{ + int rv = 0; +#ifdef HAVE_EVUTIL_SECURE_RNG_INIT + char buf[256]; + if (evutil_secure_rng_init() < 0) { + rv = -1; + } + /* Older libevent -- manually initialize the RNG */ + crypto_rand(buf, 32); + evutil_secure_rng_add_bytes(buf, 32); + evutil_secure_rng_get_bytes(buf, sizeof(buf)); +#endif + return rv; +} + #if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,1,1) \ && !defined(TOR_UNIT_TESTS) void diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h index f0d1828b7b..9ee7b49cfb 100644 --- a/src/common/compat_libevent.h +++ b/src/common/compat_libevent.h @@ -89,6 +89,8 @@ int tor_add_bufferevent_to_rate_limit_group(struct bufferevent *bev, struct bufferevent_rate_limit_group *g); #endif +int tor_init_libevent_rng(void); + void tor_gettimeofday_cached(struct timeval *tv); void tor_gettimeofday_cache_clear(void); #ifdef TOR_UNIT_TESTS diff --git a/src/common/sandbox.c b/src/common/sandbox.c index 2a1ddd13d1..40f2003096 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -124,7 +124,6 @@ static int filter_nopar_gen[] = { SCMP_SYS(read), SCMP_SYS(rt_sigreturn), SCMP_SYS(set_robust_list), - SCMP_SYS(_sysctl), #ifdef __NR_sigreturn SCMP_SYS(sigreturn), #endif @@ -373,6 +372,23 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } +static int +sb__sysctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) +{ + int rc; + (void) filter; + (void) ctx; + + rc = seccomp_rule_add_0(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(_sysctl)); + if (rc != 0) { + log_err(LD_BUG,"(Sandbox) failed to add _sysctl syscall, " + "received libseccomp error %d", rc); + return rc; + } + + return 0; +} + /** * Function responsible for setting up the rename syscall for * the seccomp filter sandbox. @@ -850,6 +866,7 @@ static sandbox_filter_func_t filter_func[] = { #endif sb_open, sb_openat, + sb__sysctl, sb_rename, #ifdef __NR_fcntl64 sb_fcntl64, diff --git a/src/or/main.c b/src/or/main.c index 341f22adcb..c0f14c0b89 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -2432,6 +2432,9 @@ tor_init(int argc, char *argv[]) return -1; } stream_choice_seed_weak_rng(); + if (tor_init_libevent_rng() < 0) { + log_warn(LD_NET, "Problem initializing libevent RNG."); + } return 0; } @@ -2723,6 +2726,7 @@ init_addrinfo(void) static sandbox_cfg_t* sandbox_init_filter(void) { + const or_options_t *options = get_options(); sandbox_cfg_t *cfg = sandbox_cfg_new(); sandbox_cfg_allow_openat_filename(&cfg, @@ -2761,8 +2765,14 @@ sandbox_init_filter(void) tor_strdup("/dev/srandom"), tor_strdup("/dev/urandom"), tor_strdup("/dev/random"), + tor_strdup("/etc/hosts"), NULL, 0 ); + if (options->ServerDNSResolvConfFile) + sandbox_cfg_allow_open_filename(&cfg, + tor_strdup(options->ServerDNSResolvConfFile)); + else + sandbox_cfg_allow_open_filename(&cfg, tor_strdup("/etc/resolv.conf")); #define RENAME_SUFFIX(name, suffix) \ sandbox_cfg_allow_rename(&cfg, \ |