aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-04-16 15:17:23 -0400
committerNick Mathewson <nickm@torproject.org>2014-04-16 22:03:10 -0400
commit69eb2788302aa96e7d37597c407e8f7da4e8a96f (patch)
treeafba1d2443b9137c203e4afab8004891235e89fd /src/common
parentce776cf2700e5bb484630bc287b31204162adfac (diff)
downloadtor-69eb2788302aa96e7d37597c407e8f7da4e8a96f.tar
tor-69eb2788302aa96e7d37597c407e8f7da4e8a96f.tar.gz
Use SCMP_CMP_MASKED_EQ to allow flags, not force them
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!)
Diffstat (limited to 'src/common')
-rw-r--r--src/common/sandbox.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index 40f200309..5f9d625ef 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -77,6 +77,13 @@ 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_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
+ * mask, since otherwise the negation might get applied to a 32 bit value, and
+ * the high bits of the value might get masked out improperly. */
+#define SCMP_CMP_MASKED(a,b,c) \
+ SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c))
/** Variable used for storing all syscall numbers that will be allowed with the
* stage 1 general Tor sandbox.
@@ -258,12 +265,7 @@ sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
#endif
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4),
- SCMP_CMP(3, SCMP_CMP_EQ, SOCK_CLOEXEC));
- if (rc) {
- return rc;
- }
- rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4),
- SCMP_CMP(3, SCMP_CMP_EQ, SOCK_CLOEXEC|SOCK_NONBLOCK));
+ SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0));
if (rc) {
return rc;
}
@@ -362,7 +364,7 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
}
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(-1), SCMP_SYS(open),
- SCMP_CMP(1, SCMP_CMP_EQ, O_RDONLY|O_CLOEXEC));
+ SCMP_CMP_MASKED(1, O_CLOEXEC, O_RDONLY));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp "
"error %d", rc);
@@ -460,6 +462,7 @@ static int
sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
{
int rc = 0;
+ int i;
(void) filter;
#ifdef __i386__
@@ -468,33 +471,29 @@ sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return rc;
#endif
- rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
+ rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
- SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK),
- SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP));
+ SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM));
if (rc)
return rc;
- rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
- SCMP_CMP(0, SCMP_CMP_EQ, PF_INET),
- SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC),
- SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_TCP));
- if (rc)
- return rc;
+ for (i = 0; i < 2; ++i) {
+ const int pf = i ? PF_INET : PF_INET6;
- rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
- SCMP_CMP(0, SCMP_CMP_EQ, PF_INET),
- SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK),
+ rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
+ SCMP_CMP(0, SCMP_CMP_EQ, pf),
+ SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM),
SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_TCP));
- if (rc)
- return rc;
+ if (rc)
+ return rc;
- rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
- SCMP_CMP(0, SCMP_CMP_EQ, PF_INET),
- SCMP_CMP(1, SCMP_CMP_EQ, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK),
+ rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
+ SCMP_CMP(0, SCMP_CMP_EQ, pf),
+ SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_DGRAM),
SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP));
- if (rc)
- return rc;
+ if (rc)
+ return rc;
+ }
rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
SCMP_CMP(0, SCMP_CMP_EQ, PF_NETLINK),