The server cipher list is (thanks to #11513) chosen systematically to
put the best choices for Tor first. The client cipher list is chosen
to resemble a browser. So let's set SSL_OP_CIPHER_SERVER_PREFERENCE
to have the servers pick according to their own preference order.
This means that tor can run without needing to communicate with ioctls
to the firewall, and therefore doesn't need to run with privileges to
open the /dev/pf device node.
A new TransProxyType is added for this purpose, "pf-divert"; if the user
specifies this TransProxyType in their torrc, then the pf device node is
never opened and the connection destination is determined with getsockname
(as per pf(4)). The default behaviour (ie., when TransProxyType is "default"
when using the pf firewall) is still to assume that pf is configured with
rdr-to rules.
This isn't on by default; to get it, you need to set "TransProxyType
ipfw". (The original patch had automatic detection for whether
/dev/pf is present and openable, but that seems marginally fragile.)
Older versions of Libevent are happy to open SOCK_DGRAM sockets
non-cloexec and non-nonblocking, and then set those flags
afterwards. It's nice to be able to allow a flag to be on or off in
the sandbox without having to enumerate all its values.
Also, permit PF_INET6 sockets. (D'oh!)
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.
The compiler doesn't warn about this code:
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 1,
SCMP_CMP(0, SCMP_CMP_EQ, AT_FDCWD),
SCMP_CMP(1, SCMP_CMP_EQ, param->value),
SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|...));
but note that the arg_cnt argument above is only 1. This means that
only the first filter (argument 0 == AT_FDCWD) is actually checked!
This patch also fixes the above error in the openat() filter.
Earlier I fixed corresponding errors in filters for rename() and
mprotect().
Appearently, the majority of the filenames we pass to
sandbox_cfg_allow() functions are "freeable right after". So, consider
_all_ of them safe-to-steal, and add a tor_strdup() in the few cases
that aren't.
(Maybe buggy; revise when I can test.)
(If we don't restrict rename, there's not much point in restricting
open, since an attacker could always use rename to make us open
whatever they want.)