Skip to content
Snippets Groups Projects
Commit e6785ee1 authored by Nick Mathewson's avatar Nick Mathewson :game_die:
Browse files

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.
parent 156eefca
Branches
Tags
No related merge requests found
......@@ -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>
......
......@@ -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
......
......@@ -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
......
......@@ -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,
......
......@@ -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, \
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment