seccomp2: Add "shutdown" to the list of permitted system calls.
[tor.git] / src / common / sandbox.c
blob3b21322d31bd1ab15bda50461940411bf9c17924
1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2016, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
7 /**
8 * \file sandbox.c
9 * \brief Code to enable sandboxing.
10 **/
12 #include "orconfig.h"
14 #ifndef _LARGEFILE64_SOURCE
15 /**
16 * Temporarily required for O_LARGEFILE flag. Needs to be removed
17 * with the libevent fix.
19 #define _LARGEFILE64_SOURCE
20 #endif
22 /** Malloc mprotect limit in bytes. */
23 #define MALLOC_MP_LIM 1048576
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
29 #include "sandbox.h"
30 #include "container.h"
31 #include "torlog.h"
32 #include "torint.h"
33 #include "util.h"
34 #include "tor_queue.h"
36 #include "ht.h"
38 #define DEBUGGING_CLOSE
40 #if defined(USE_LIBSECCOMP)
42 #include <sys/mman.h>
43 #include <sys/syscall.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <sys/epoll.h>
47 #include <sys/prctl.h>
48 #include <linux/futex.h>
49 #include <sys/file.h>
51 #include <stdarg.h>
52 #include <seccomp.h>
53 #include <signal.h>
54 #include <unistd.h>
55 #include <fcntl.h>
56 #include <time.h>
57 #include <poll.h>
59 #ifdef HAVE_GNU_LIBC_VERSION_H
60 #include <gnu/libc-version.h>
61 #endif
62 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
63 #include <linux/netfilter_ipv4.h>
64 #endif
65 #ifdef HAVE_LINUX_IF_H
66 #include <linux/if.h>
67 #endif
68 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
69 #include <linux/netfilter_ipv6/ip6_tables.h>
70 #endif
72 #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
73 defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
74 #define USE_BACKTRACE
75 #define EXPOSE_CLEAN_BACKTRACE
76 #include "backtrace.h"
77 #endif
79 #ifdef USE_BACKTRACE
80 #include <execinfo.h>
81 #endif
83 /**
84 * Linux 32 bit definitions
86 #if defined(__i386__)
88 #define REG_SYSCALL REG_EAX
89 #define M_SYSCALL gregs[REG_SYSCALL]
91 /**
92 * Linux 64 bit definitions
94 #elif defined(__x86_64__)
96 #define REG_SYSCALL REG_RAX
97 #define M_SYSCALL gregs[REG_SYSCALL]
99 #elif defined(__arm__)
101 #define M_SYSCALL arm_r7
103 #endif
105 /**Determines if at least one sandbox is active.*/
106 static int sandbox_active = 0;
107 /** Holds the parameter list configuration for the sandbox.*/
108 static sandbox_cfg_t *filter_dynamic = NULL;
110 #undef SCMP_CMP
111 #define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0})
112 #define SCMP_CMP_STR(a,b,c) \
113 ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0})
114 #define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)})
115 /* We use a wrapper here because these masked comparisons seem to be pretty
116 * verbose. Also, it's important to cast to scmp_datum_t before negating the
117 * mask, since otherwise the negation might get applied to a 32 bit value, and
118 * the high bits of the value might get masked out improperly. */
119 #define SCMP_CMP_MASKED(a,b,c) \
120 SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c))
122 /** Variable used for storing all syscall numbers that will be allowed with the
123 * stage 1 general Tor sandbox.
125 static int filter_nopar_gen[] = {
126 SCMP_SYS(access),
127 SCMP_SYS(brk),
128 SCMP_SYS(clock_gettime),
129 SCMP_SYS(close),
130 SCMP_SYS(clone),
131 SCMP_SYS(epoll_create),
132 SCMP_SYS(epoll_wait),
133 #ifdef __NR_epoll_pwait
134 SCMP_SYS(epoll_pwait),
135 #endif
136 #ifdef HAVE_EVENTFD
137 SCMP_SYS(eventfd2),
138 #endif
139 #ifdef HAVE_PIPE2
140 SCMP_SYS(pipe2),
141 #endif
142 #ifdef HAVE_PIPE
143 SCMP_SYS(pipe),
144 #endif
145 #ifdef __NR_fchmod
146 SCMP_SYS(fchmod),
147 #endif
148 SCMP_SYS(fcntl),
149 SCMP_SYS(fstat),
150 #ifdef __NR_fstat64
151 SCMP_SYS(fstat64),
152 #endif
153 SCMP_SYS(futex),
154 SCMP_SYS(getdents64),
155 SCMP_SYS(getegid),
156 #ifdef __NR_getegid32
157 SCMP_SYS(getegid32),
158 #endif
159 SCMP_SYS(geteuid),
160 #ifdef __NR_geteuid32
161 SCMP_SYS(geteuid32),
162 #endif
163 SCMP_SYS(getgid),
164 #ifdef __NR_getgid32
165 SCMP_SYS(getgid32),
166 #endif
167 SCMP_SYS(getpid),
168 #ifdef __NR_getrlimit
169 SCMP_SYS(getrlimit),
170 #endif
171 SCMP_SYS(gettimeofday),
172 SCMP_SYS(gettid),
173 SCMP_SYS(getuid),
174 #ifdef __NR_getuid32
175 SCMP_SYS(getuid32),
176 #endif
177 SCMP_SYS(lseek),
178 #ifdef __NR__llseek
179 SCMP_SYS(_llseek),
180 #endif
181 SCMP_SYS(mkdir),
182 SCMP_SYS(mlockall),
183 #ifdef __NR_mmap
184 /* XXXX restrict this in the same ways as mmap2 */
185 SCMP_SYS(mmap),
186 #endif
187 SCMP_SYS(munmap),
188 #ifdef __NR_nanosleep
189 SCMP_SYS(nanosleep),
190 #endif
191 #ifdef __NR_prlimit
192 SCMP_SYS(prlimit),
193 #endif
194 #ifdef __NR_prlimit64
195 SCMP_SYS(prlimit64),
196 #endif
197 SCMP_SYS(read),
198 SCMP_SYS(rt_sigreturn),
199 SCMP_SYS(sched_getaffinity),
200 #ifdef __NR_sched_yield
201 SCMP_SYS(sched_yield),
202 #endif
203 SCMP_SYS(sendmsg),
204 SCMP_SYS(set_robust_list),
205 #ifdef __NR_setrlimit
206 SCMP_SYS(setrlimit),
207 #endif
208 SCMP_SYS(shutdown),
209 #ifdef __NR_sigaltstack
210 SCMP_SYS(sigaltstack),
211 #endif
212 #ifdef __NR_sigreturn
213 SCMP_SYS(sigreturn),
214 #endif
215 SCMP_SYS(stat),
216 SCMP_SYS(uname),
217 SCMP_SYS(wait4),
218 SCMP_SYS(write),
219 SCMP_SYS(writev),
220 SCMP_SYS(exit_group),
221 SCMP_SYS(exit),
223 SCMP_SYS(madvise),
224 #ifdef __NR_stat64
225 // getaddrinfo uses this..
226 SCMP_SYS(stat64),
227 #endif
229 #ifdef __NR_getrandom
230 SCMP_SYS(getrandom),
231 #endif
233 #ifdef __NR_sysinfo
234 // qsort uses this..
235 SCMP_SYS(sysinfo),
236 #endif
238 * These socket syscalls are not required on x86_64 and not supported with
239 * some libseccomp versions (eg: 1.0.1)
241 #if defined(__i386)
242 SCMP_SYS(recv),
243 SCMP_SYS(send),
244 #endif
246 // socket syscalls
247 SCMP_SYS(bind),
248 SCMP_SYS(listen),
249 SCMP_SYS(connect),
250 SCMP_SYS(getsockname),
251 SCMP_SYS(recvmsg),
252 SCMP_SYS(recvfrom),
253 SCMP_SYS(sendto),
254 SCMP_SYS(unlink),
255 SCMP_SYS(poll)
258 /* These macros help avoid the error where the number of filters we add on a
259 * single rule don't match the arg_cnt param. */
260 #define seccomp_rule_add_0(ctx,act,call) \
261 seccomp_rule_add((ctx),(act),(call),0)
262 #define seccomp_rule_add_1(ctx,act,call,f1) \
263 seccomp_rule_add((ctx),(act),(call),1,(f1))
264 #define seccomp_rule_add_2(ctx,act,call,f1,f2) \
265 seccomp_rule_add((ctx),(act),(call),2,(f1),(f2))
266 #define seccomp_rule_add_3(ctx,act,call,f1,f2,f3) \
267 seccomp_rule_add((ctx),(act),(call),3,(f1),(f2),(f3))
268 #define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \
269 seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4))
272 * Function responsible for setting up the rt_sigaction syscall for
273 * the seccomp filter sandbox.
275 static int
276 sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
278 unsigned i;
279 int rc;
280 int param[] = { SIGINT, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, SIGHUP, SIGCHLD,
281 #ifdef SIGXFSZ
282 SIGXFSZ
283 #endif
285 (void) filter;
287 for (i = 0; i < ARRAY_LENGTH(param); i++) {
288 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction),
289 SCMP_CMP(0, SCMP_CMP_EQ, param[i]));
290 if (rc)
291 break;
294 return rc;
297 #if 0
299 * Function responsible for setting up the execve syscall for
300 * the seccomp filter sandbox.
302 static int
303 sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
305 int rc;
306 sandbox_cfg_t *elem = NULL;
308 // for each dynamic parameter filters
309 for (elem = filter; elem != NULL; elem = elem->next) {
310 smp_param_t *param = elem->param;
312 if (param != NULL && param->prot == 1 && param->syscall
313 == SCMP_SYS(execve)) {
314 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve),
315 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
316 if (rc != 0) {
317 log_err(LD_BUG,"(Sandbox) failed to add execve syscall, received "
318 "libseccomp error %d", rc);
319 return rc;
324 return 0;
326 #endif
329 * Function responsible for setting up the time syscall for
330 * the seccomp filter sandbox.
332 static int
333 sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
335 (void) filter;
336 #ifdef __NR_time
337 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time),
338 SCMP_CMP(0, SCMP_CMP_EQ, 0));
339 #else
340 return 0;
341 #endif
345 * Function responsible for setting up the accept4 syscall for
346 * the seccomp filter sandbox.
348 static int
349 sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
351 int rc = 0;
352 (void)filter;
354 #ifdef __i386__
355 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall),
356 SCMP_CMP(0, SCMP_CMP_EQ, 18));
357 if (rc) {
358 return rc;
360 #endif
362 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4),
363 SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0));
364 if (rc) {
365 return rc;
368 return 0;
371 #ifdef __NR_mmap2
373 * Function responsible for setting up the mmap2 syscall for
374 * the seccomp filter sandbox.
376 static int
377 sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
379 int rc = 0;
380 (void)filter;
382 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
383 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ),
384 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE));
385 if (rc) {
386 return rc;
389 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
390 SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE),
391 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE));
392 if (rc) {
393 return rc;
396 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
397 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
398 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS));
399 if (rc) {
400 return rc;
403 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
404 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
405 SCMP_CMP(3, SCMP_CMP_EQ,MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK));
406 if (rc) {
407 return rc;
410 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
411 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
412 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE));
413 if (rc) {
414 return rc;
417 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
418 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
419 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS));
420 if (rc) {
421 return rc;
424 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
425 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_EXEC),
426 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_DENYWRITE));
427 if (rc) {
428 return rc;
431 return 0;
433 #endif
435 #ifdef HAVE_GNU_LIBC_VERSION_H
436 #ifdef HAVE_GNU_GET_LIBC_VERSION
437 #define CHECK_LIBC_VERSION
438 #endif
439 #endif
441 /* Return true if we think we're running with a libc that always uses
442 * openat on linux. */
443 static int
444 libc_uses_openat_for_everything(void)
446 #ifdef CHECK_LIBC_VERSION
447 const char *version = gnu_get_libc_version();
448 if (version == NULL)
449 return 0;
451 int major = -1;
452 int minor = -1;
454 tor_sscanf(version, "%d.%d", &major, &minor);
455 if (major >= 3)
456 return 1;
457 else if (major == 2 && minor >= 26)
458 return 1;
459 else
460 return 0;
461 #else
462 return 0;
463 #endif
466 /** Allow a single file to be opened. If <b>use_openat</b> is true,
467 * we're using a libc that remaps all the opens into openats. */
468 static int
469 allow_file_open(scmp_filter_ctx ctx, int use_openat, const char *file)
471 if (use_openat) {
472 return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
473 SCMP_CMP(0, SCMP_CMP_EQ, (unsigned int)AT_FDCWD),
474 SCMP_CMP_STR(1, SCMP_CMP_EQ, file));
475 } else {
476 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),
477 SCMP_CMP_STR(0, SCMP_CMP_EQ, file));
482 * Function responsible for setting up the open syscall for
483 * the seccomp filter sandbox.
485 static int
486 sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
488 int rc;
489 sandbox_cfg_t *elem = NULL;
491 int use_openat = libc_uses_openat_for_everything();
493 // for each dynamic parameter filters
494 for (elem = filter; elem != NULL; elem = elem->next) {
495 smp_param_t *param = elem->param;
497 if (param != NULL && param->prot == 1 && param->syscall
498 == SCMP_SYS(open)) {
499 rc = allow_file_open(ctx, use_openat, param->value);
500 if (rc != 0) {
501 log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
502 "libseccomp error %d", rc);
503 return rc;
508 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open),
509 SCMP_CMP_MASKED(1, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW,
510 O_RDONLY));
511 if (rc != 0) {
512 log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp "
513 "error %d", rc);
514 return rc;
517 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(openat),
518 SCMP_CMP_MASKED(2, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW,
519 O_RDONLY));
520 if (rc != 0) {
521 log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
522 "libseccomp error %d", rc);
523 return rc;
526 return 0;
529 static int
530 sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
532 int rc;
533 sandbox_cfg_t *elem = NULL;
535 // for each dynamic parameter filters
536 for (elem = filter; elem != NULL; elem = elem->next) {
537 smp_param_t *param = elem->param;
539 if (param != NULL && param->prot == 1 && param->syscall
540 == SCMP_SYS(chmod)) {
541 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod),
542 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
543 if (rc != 0) {
544 log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
545 "libseccomp error %d", rc);
546 return rc;
551 return 0;
554 static int
555 sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
557 int rc;
558 sandbox_cfg_t *elem = NULL;
560 // for each dynamic parameter filters
561 for (elem = filter; elem != NULL; elem = elem->next) {
562 smp_param_t *param = elem->param;
564 if (param != NULL && param->prot == 1 && param->syscall
565 == SCMP_SYS(chown)) {
566 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown),
567 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
568 if (rc != 0) {
569 log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
570 "libseccomp error %d", rc);
571 return rc;
576 return 0;
579 static int
580 sb__sysctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
582 int rc;
583 (void) filter;
584 (void) ctx;
586 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(_sysctl));
587 if (rc != 0) {
588 log_err(LD_BUG,"(Sandbox) failed to add _sysctl syscall, "
589 "received libseccomp error %d", rc);
590 return rc;
593 return 0;
597 * Function responsible for setting up the rename syscall for
598 * the seccomp filter sandbox.
600 static int
601 sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
603 int rc;
604 sandbox_cfg_t *elem = NULL;
606 // for each dynamic parameter filters
607 for (elem = filter; elem != NULL; elem = elem->next) {
608 smp_param_t *param = elem->param;
610 if (param != NULL && param->prot == 1 &&
611 param->syscall == SCMP_SYS(rename)) {
613 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename),
614 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value),
615 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2));
616 if (rc != 0) {
617 log_err(LD_BUG,"(Sandbox) failed to add rename syscall, received "
618 "libseccomp error %d", rc);
619 return rc;
624 return 0;
628 * Function responsible for setting up the openat syscall for
629 * the seccomp filter sandbox.
631 static int
632 sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
634 int rc;
635 sandbox_cfg_t *elem = NULL;
637 // for each dynamic parameter filters
638 for (elem = filter; elem != NULL; elem = elem->next) {
639 smp_param_t *param = elem->param;
641 if (param != NULL && param->prot == 1 && param->syscall
642 == SCMP_SYS(openat)) {
643 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
644 SCMP_CMP(0, SCMP_CMP_EQ, AT_FDCWD),
645 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
646 SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
647 O_CLOEXEC));
648 if (rc != 0) {
649 log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
650 "libseccomp error %d", rc);
651 return rc;
656 return 0;
660 * Function responsible for setting up the socket syscall for
661 * the seccomp filter sandbox.
663 static int
664 sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
666 int rc = 0;
667 int i, j;
668 (void) filter;
670 #ifdef __i386__
671 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket));
672 if (rc)
673 return rc;
674 #endif
676 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
677 SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
678 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM));
679 if (rc)
680 return rc;
682 for (i = 0; i < 2; ++i) {
683 const int pf = i ? PF_INET : PF_INET6;
684 for (j=0; j < 3; ++j) {
685 const int type = (j == 0) ? SOCK_STREAM :
686 SOCK_DGRAM;
687 const int protocol = (j == 0) ? IPPROTO_TCP :
688 (j == 1) ? IPPROTO_IP :
689 IPPROTO_UDP;
690 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
691 SCMP_CMP(0, SCMP_CMP_EQ, pf),
692 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, type),
693 SCMP_CMP(2, SCMP_CMP_EQ, protocol));
694 if (rc)
695 return rc;
699 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
700 SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
701 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM),
702 SCMP_CMP(2, SCMP_CMP_EQ, 0));
703 if (rc)
704 return rc;
706 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
707 SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
708 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_DGRAM),
709 SCMP_CMP(2, SCMP_CMP_EQ, 0));
710 if (rc)
711 return rc;
713 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
714 SCMP_CMP(0, SCMP_CMP_EQ, PF_NETLINK),
715 SCMP_CMP_MASKED(1, SOCK_CLOEXEC, SOCK_RAW),
716 SCMP_CMP(2, SCMP_CMP_EQ, 0));
717 if (rc)
718 return rc;
720 return 0;
724 * Function responsible for setting up the socketpair syscall for
725 * the seccomp filter sandbox.
727 static int
728 sb_socketpair(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
730 int rc = 0;
731 (void) filter;
733 #ifdef __i386__
734 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair));
735 if (rc)
736 return rc;
737 #endif
739 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair),
740 SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
741 SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC));
742 if (rc)
743 return rc;
745 return 0;
749 * Function responsible for setting up the setsockopt syscall for
750 * the seccomp filter sandbox.
752 static int
753 sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
755 int rc = 0;
756 (void) filter;
758 #ifdef __i386__
759 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt));
760 if (rc)
761 return rc;
762 #endif
764 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
765 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
766 SCMP_CMP(2, SCMP_CMP_EQ, SO_REUSEADDR));
767 if (rc)
768 return rc;
770 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
771 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
772 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
773 if (rc)
774 return rc;
776 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
777 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
778 SCMP_CMP(2, SCMP_CMP_EQ, SO_RCVBUF));
779 if (rc)
780 return rc;
782 #ifdef HAVE_SYSTEMD
783 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
784 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
785 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUFFORCE));
786 if (rc)
787 return rc;
788 #endif
790 #ifdef IP_TRANSPARENT
791 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
792 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
793 SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT));
794 if (rc)
795 return rc;
796 #endif
798 #ifdef IPV6_V6ONLY
799 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
800 SCMP_CMP(1, SCMP_CMP_EQ, IPPROTO_IPV6),
801 SCMP_CMP(2, SCMP_CMP_EQ, IPV6_V6ONLY));
802 if (rc)
803 return rc;
804 #endif
806 return 0;
810 * Function responsible for setting up the getsockopt syscall for
811 * the seccomp filter sandbox.
813 static int
814 sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
816 int rc = 0;
817 (void) filter;
819 #ifdef __i386__
820 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt));
821 if (rc)
822 return rc;
823 #endif
825 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
826 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
827 SCMP_CMP(2, SCMP_CMP_EQ, SO_ERROR));
828 if (rc)
829 return rc;
831 #ifdef HAVE_SYSTEMD
832 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
833 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
834 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
835 if (rc)
836 return rc;
837 #endif
839 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
840 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
841 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
842 SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST));
843 if (rc)
844 return rc;
845 #endif
847 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
848 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
849 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6),
850 SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST));
851 if (rc)
852 return rc;
853 #endif
855 return 0;
858 #ifdef __NR_fcntl64
860 * Function responsible for setting up the fcntl64 syscall for
861 * the seccomp filter sandbox.
863 static int
864 sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
866 int rc = 0;
867 (void) filter;
869 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
870 SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL));
871 if (rc)
872 return rc;
874 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
875 SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL),
876 SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK));
877 if (rc)
878 return rc;
880 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
881 SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD));
882 if (rc)
883 return rc;
885 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
886 SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD),
887 SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC));
888 if (rc)
889 return rc;
891 return 0;
893 #endif
896 * Function responsible for setting up the epoll_ctl syscall for
897 * the seccomp filter sandbox.
899 * Note: basically allows everything but will keep for now..
901 static int
902 sb_epoll_ctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
904 int rc = 0;
905 (void) filter;
907 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
908 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD));
909 if (rc)
910 return rc;
912 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
913 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD));
914 if (rc)
915 return rc;
917 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
918 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL));
919 if (rc)
920 return rc;
922 return 0;
926 * Function responsible for setting up the prctl syscall for
927 * the seccomp filter sandbox.
929 * NOTE: if multiple filters need to be added, the PR_SECCOMP parameter needs
930 * to be whitelisted in this function.
932 static int
933 sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
935 int rc = 0;
936 (void) filter;
938 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
939 SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE));
940 if (rc)
941 return rc;
943 return 0;
947 * Function responsible for setting up the mprotect syscall for
948 * the seccomp filter sandbox.
950 * NOTE: does not NEED to be here.. currently only occurs before filter; will
951 * keep just in case for the future.
953 static int
954 sb_mprotect(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
956 int rc = 0;
957 (void) filter;
959 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
960 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ));
961 if (rc)
962 return rc;
964 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
965 SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE));
966 if (rc)
967 return rc;
969 return 0;
973 * Function responsible for setting up the rt_sigprocmask syscall for
974 * the seccomp filter sandbox.
976 static int
977 sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
979 int rc = 0;
980 (void) filter;
982 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
983 SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK));
984 if (rc)
985 return rc;
987 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
988 SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK));
989 if (rc)
990 return rc;
992 return 0;
996 * Function responsible for setting up the flock syscall for
997 * the seccomp filter sandbox.
999 * NOTE: does not need to be here, occurs before filter is applied.
1001 static int
1002 sb_flock(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1004 int rc = 0;
1005 (void) filter;
1007 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1008 SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB));
1009 if (rc)
1010 return rc;
1012 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1013 SCMP_CMP(1, SCMP_CMP_EQ, LOCK_UN));
1014 if (rc)
1015 return rc;
1017 return 0;
1021 * Function responsible for setting up the futex syscall for
1022 * the seccomp filter sandbox.
1024 static int
1025 sb_futex(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1027 int rc = 0;
1028 (void) filter;
1030 // can remove
1031 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1032 SCMP_CMP(1, SCMP_CMP_EQ,
1033 FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME));
1034 if (rc)
1035 return rc;
1037 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1038 SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
1039 if (rc)
1040 return rc;
1042 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1043 SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE));
1044 if (rc)
1045 return rc;
1047 return 0;
1051 * Function responsible for setting up the mremap syscall for
1052 * the seccomp filter sandbox.
1054 * NOTE: so far only occurs before filter is applied.
1056 static int
1057 sb_mremap(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1059 int rc = 0;
1060 (void) filter;
1062 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap),
1063 SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE));
1064 if (rc)
1065 return rc;
1067 return 0;
1070 #ifdef __NR_stat64
1072 * Function responsible for setting up the stat64 syscall for
1073 * the seccomp filter sandbox.
1075 static int
1076 sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1078 int rc = 0;
1079 sandbox_cfg_t *elem = NULL;
1081 // for each dynamic parameter filters
1082 for (elem = filter; elem != NULL; elem = elem->next) {
1083 smp_param_t *param = elem->param;
1085 if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
1086 || param->syscall == SCMP_SYS(stat64))) {
1087 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64),
1088 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
1089 if (rc != 0) {
1090 log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
1091 "libseccomp error %d", rc);
1092 return rc;
1097 return 0;
1099 #endif
1101 static int
1102 sb_kill(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1104 (void) filter;
1105 #ifdef __NR_kill
1106 /* Allow killing anything with signal 0 -- it isn't really a kill. */
1107 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(kill),
1108 SCMP_CMP(1, SCMP_CMP_EQ, 0));
1109 #else
1110 return 0;
1111 #endif
1115 * Array of function pointers responsible for filtering different syscalls at
1116 * a parameter level.
1118 static sandbox_filter_func_t filter_func[] = {
1119 sb_rt_sigaction,
1120 sb_rt_sigprocmask,
1121 #if 0
1122 sb_execve,
1123 #endif
1124 sb_time,
1125 sb_accept4,
1126 #ifdef __NR_mmap2
1127 sb_mmap2,
1128 #endif
1129 sb_chown,
1130 sb_chmod,
1131 sb_open,
1132 sb_openat,
1133 sb__sysctl,
1134 sb_rename,
1135 #ifdef __NR_fcntl64
1136 sb_fcntl64,
1137 #endif
1138 sb_epoll_ctl,
1139 sb_prctl,
1140 sb_mprotect,
1141 sb_flock,
1142 sb_futex,
1143 sb_mremap,
1144 #ifdef __NR_stat64
1145 sb_stat64,
1146 #endif
1148 sb_socket,
1149 sb_setsockopt,
1150 sb_getsockopt,
1151 sb_socketpair,
1152 sb_kill
1155 const char *
1156 sandbox_intern_string(const char *str)
1158 sandbox_cfg_t *elem;
1160 if (str == NULL)
1161 return NULL;
1163 for (elem = filter_dynamic; elem != NULL; elem = elem->next) {
1164 smp_param_t *param = elem->param;
1166 if (param->prot) {
1167 if (!strcmp(str, (char*)(param->value))) {
1168 return (char*)param->value;
1170 if (param->value2 && !strcmp(str, (char*)param->value2)) {
1171 return (char*)param->value2;
1176 if (sandbox_active)
1177 log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
1178 return str;
1181 /* DOCDOC */
1182 static int
1183 prot_strings_helper(strmap_t *locations,
1184 char **pr_mem_next_p,
1185 size_t *pr_mem_left_p,
1186 char **value_p)
1188 char *param_val;
1189 size_t param_size;
1190 void *location;
1192 if (*value_p == 0)
1193 return 0;
1195 param_val = (char*) *value_p;
1196 param_size = strlen(param_val) + 1;
1197 location = strmap_get(locations, param_val);
1199 if (location) {
1200 // We already interned this string.
1201 tor_free(param_val);
1202 *value_p = location;
1203 return 0;
1204 } else if (*pr_mem_left_p >= param_size) {
1205 // copy to protected
1206 location = *pr_mem_next_p;
1207 memcpy(location, param_val, param_size);
1209 // re-point el parameter to protected
1210 tor_free(param_val);
1211 *value_p = location;
1213 strmap_set(locations, location, location); /* good real estate advice */
1215 // move next available protected memory
1216 *pr_mem_next_p += param_size;
1217 *pr_mem_left_p -= param_size;
1218 return 0;
1219 } else {
1220 log_err(LD_BUG,"(Sandbox) insufficient protected memory!");
1221 return -1;
1226 * Protects all the strings in the sandbox's parameter list configuration. It
1227 * works by calculating the total amount of memory required by the parameter
1228 * list, allocating the memory using mmap, and protecting it from writes with
1229 * mprotect().
1231 static int
1232 prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
1234 int ret = 0;
1235 size_t pr_mem_size = 0, pr_mem_left = 0;
1236 char *pr_mem_next = NULL, *pr_mem_base;
1237 sandbox_cfg_t *el = NULL;
1238 strmap_t *locations = NULL;
1240 // get total number of bytes required to mmap. (Overestimate.)
1241 for (el = cfg; el != NULL; el = el->next) {
1242 pr_mem_size += strlen((char*) el->param->value) + 1;
1243 if (el->param->value2)
1244 pr_mem_size += strlen((char*) el->param->value2) + 1;
1247 // allocate protected memory with MALLOC_MP_LIM canary
1248 pr_mem_base = (char*) mmap(NULL, MALLOC_MP_LIM + pr_mem_size,
1249 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
1250 if (pr_mem_base == MAP_FAILED) {
1251 log_err(LD_BUG,"(Sandbox) failed allocate protected memory! mmap: %s",
1252 strerror(errno));
1253 ret = -1;
1254 goto out;
1257 pr_mem_next = pr_mem_base + MALLOC_MP_LIM;
1258 pr_mem_left = pr_mem_size;
1260 locations = strmap_new();
1262 // change el value pointer to protected
1263 for (el = cfg; el != NULL; el = el->next) {
1264 if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1265 &el->param->value) < 0) {
1266 ret = -2;
1267 goto out;
1269 if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1270 &el->param->value2) < 0) {
1271 ret = -2;
1272 goto out;
1274 el->param->prot = 1;
1277 // protecting from writes
1278 if (mprotect(pr_mem_base, MALLOC_MP_LIM + pr_mem_size, PROT_READ)) {
1279 log_err(LD_BUG,"(Sandbox) failed to protect memory! mprotect: %s",
1280 strerror(errno));
1281 ret = -3;
1282 goto out;
1286 * Setting sandbox restrictions so the string memory cannot be tampered with
1288 // no mremap of the protected base address
1289 ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(mremap),
1290 SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1291 if (ret) {
1292 log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!");
1293 goto out;
1296 // no munmap of the protected base address
1297 ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(munmap),
1298 SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1299 if (ret) {
1300 log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!");
1301 goto out;
1305 * Allow mprotect with PROT_READ|PROT_WRITE because openssl uses it, but
1306 * never over the memory region used by the protected strings.
1308 * PROT_READ|PROT_WRITE was originally fully allowed in sb_mprotect(), but
1309 * had to be removed due to limitation of libseccomp regarding intervals.
1311 * There is a restriction on how much you can mprotect with R|W up to the
1312 * size of the canary.
1314 ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1315 SCMP_CMP(0, SCMP_CMP_LT, (intptr_t) pr_mem_base),
1316 SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
1317 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1318 if (ret) {
1319 log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!");
1320 goto out;
1323 ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1324 SCMP_CMP(0, SCMP_CMP_GT, (intptr_t) pr_mem_base + pr_mem_size +
1325 MALLOC_MP_LIM),
1326 SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
1327 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1328 if (ret) {
1329 log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!");
1330 goto out;
1333 out:
1334 strmap_free(locations, NULL);
1335 return ret;
1339 * Auxiliary function used in order to allocate a sandbox_cfg_t element and set
1340 * its values according the parameter list. All elements are initialised
1341 * with the 'prot' field set to false, as the pointer is not protected at this
1342 * point.
1344 static sandbox_cfg_t*
1345 new_element2(int syscall, char *value, char *value2)
1347 smp_param_t *param = NULL;
1349 sandbox_cfg_t *elem = tor_malloc_zero(sizeof(sandbox_cfg_t));
1350 param = elem->param = tor_malloc_zero(sizeof(smp_param_t));
1352 param->syscall = syscall;
1353 param->value = value;
1354 param->value2 = value2;
1355 param->prot = 0;
1357 return elem;
1360 static sandbox_cfg_t*
1361 new_element(int syscall, char *value)
1363 return new_element2(syscall, value, NULL);
1366 #ifdef __NR_stat64
1367 #define SCMP_stat SCMP_SYS(stat64)
1368 #else
1369 #define SCMP_stat SCMP_SYS(stat)
1370 #endif
1373 sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
1375 sandbox_cfg_t *elem = NULL;
1377 elem = new_element(SCMP_stat, file);
1378 if (!elem) {
1379 log_err(LD_BUG,"(Sandbox) failed to register parameter!");
1380 return -1;
1383 elem->next = *cfg;
1384 *cfg = elem;
1386 return 0;
1390 sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
1392 sandbox_cfg_t *elem = NULL;
1394 elem = new_element(SCMP_SYS(open), file);
1395 if (!elem) {
1396 log_err(LD_BUG,"(Sandbox) failed to register parameter!");
1397 return -1;
1400 elem->next = *cfg;
1401 *cfg = elem;
1403 return 0;
1407 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
1409 sandbox_cfg_t *elem = NULL;
1411 elem = new_element(SCMP_SYS(chmod), file);
1412 if (!elem) {
1413 log_err(LD_BUG,"(Sandbox) failed to register parameter!");
1414 return -1;
1417 elem->next = *cfg;
1418 *cfg = elem;
1420 return 0;
1424 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
1426 sandbox_cfg_t *elem = NULL;
1428 elem = new_element(SCMP_SYS(chown), file);
1429 if (!elem) {
1430 log_err(LD_BUG,"(Sandbox) failed to register parameter!");
1431 return -1;
1434 elem->next = *cfg;
1435 *cfg = elem;
1437 return 0;
1441 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
1443 sandbox_cfg_t *elem = NULL;
1445 elem = new_element2(SCMP_SYS(rename), file1, file2);
1447 if (!elem) {
1448 log_err(LD_BUG,"(Sandbox) failed to register parameter!");
1449 return -1;
1452 elem->next = *cfg;
1453 *cfg = elem;
1455 return 0;
1459 sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
1461 sandbox_cfg_t *elem = NULL;
1463 elem = new_element(SCMP_SYS(openat), file);
1464 if (!elem) {
1465 log_err(LD_BUG,"(Sandbox) failed to register parameter!");
1466 return -1;
1469 elem->next = *cfg;
1470 *cfg = elem;
1472 return 0;
1475 #if 0
1477 sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
1479 sandbox_cfg_t *elem = NULL;
1481 elem = new_element(SCMP_SYS(execve), com);
1482 if (!elem) {
1483 log_err(LD_BUG,"(Sandbox) failed to register parameter!");
1484 return -1;
1487 elem->next = *cfg;
1488 *cfg = elem;
1490 return 0;
1493 #endif
1495 /** Cache entry for getaddrinfo results; used when sandboxing is implemented
1496 * so that we can consult the cache when the sandbox prevents us from doing
1497 * getaddrinfo.
1499 * We support only a limited range of getaddrinfo calls, where servname is null
1500 * and hints contains only socktype=SOCK_STREAM, family in INET,INET6,UNSPEC.
1502 typedef struct cached_getaddrinfo_item_t {
1503 HT_ENTRY(cached_getaddrinfo_item_t) node;
1504 char *name;
1505 int family;
1506 /** set if no error; otherwise NULL */
1507 struct addrinfo *res;
1508 /** 0 for no error; otherwise an EAI_* value */
1509 int err;
1510 } cached_getaddrinfo_item_t;
1512 static unsigned
1513 cached_getaddrinfo_item_hash(const cached_getaddrinfo_item_t *item)
1515 return (unsigned)siphash24g(item->name, strlen(item->name)) + item->family;
1518 static unsigned
1519 cached_getaddrinfo_items_eq(const cached_getaddrinfo_item_t *a,
1520 const cached_getaddrinfo_item_t *b)
1522 return (a->family == b->family) && 0 == strcmp(a->name, b->name);
1525 static void
1526 cached_getaddrinfo_item_free(cached_getaddrinfo_item_t *item)
1528 if (item == NULL)
1529 return;
1531 tor_free(item->name);
1532 if (item->res)
1533 freeaddrinfo(item->res);
1534 tor_free(item);
1537 static HT_HEAD(getaddrinfo_cache, cached_getaddrinfo_item_t)
1538 getaddrinfo_cache = HT_INITIALIZER();
1540 HT_PROTOTYPE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
1541 cached_getaddrinfo_item_hash,
1542 cached_getaddrinfo_items_eq)
1543 HT_GENERATE2(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
1544 cached_getaddrinfo_item_hash,
1545 cached_getaddrinfo_items_eq,
1546 0.6, tor_reallocarray_, tor_free_)
1548 /** If true, don't try to cache getaddrinfo results. */
1549 static int sandbox_getaddrinfo_cache_disabled = 0;
1551 /** Tell the sandbox layer not to try to cache getaddrinfo results. Used as in
1552 * tor-resolve, when we have no intention of initializing crypto or of
1553 * installing the sandbox.*/
1554 void
1555 sandbox_disable_getaddrinfo_cache(void)
1557 sandbox_getaddrinfo_cache_disabled = 1;
1560 void
1561 sandbox_freeaddrinfo(struct addrinfo *ai)
1563 if (sandbox_getaddrinfo_cache_disabled)
1564 freeaddrinfo(ai);
1568 sandbox_getaddrinfo(const char *name, const char *servname,
1569 const struct addrinfo *hints,
1570 struct addrinfo **res)
1572 int err;
1573 struct cached_getaddrinfo_item_t search, *item;
1575 if (sandbox_getaddrinfo_cache_disabled) {
1576 return getaddrinfo(name, NULL, hints, res);
1579 if (servname != NULL) {
1580 log_warn(LD_BUG, "called with non-NULL servname");
1581 return EAI_NONAME;
1583 if (name == NULL) {
1584 log_warn(LD_BUG, "called with NULL name");
1585 return EAI_NONAME;
1588 *res = NULL;
1590 memset(&search, 0, sizeof(search));
1591 search.name = (char *) name;
1592 search.family = hints ? hints->ai_family : AF_UNSPEC;
1593 item = HT_FIND(getaddrinfo_cache, &getaddrinfo_cache, &search);
1595 if (! sandbox_is_active()) {
1596 /* If the sandbox is not turned on yet, then getaddrinfo and store the
1597 result. */
1599 err = getaddrinfo(name, NULL, hints, res);
1600 log_info(LD_NET,"(Sandbox) getaddrinfo %s.", err ? "failed" : "succeeded");
1602 if (! item) {
1603 item = tor_malloc_zero(sizeof(*item));
1604 item->name = tor_strdup(name);
1605 item->family = hints ? hints->ai_family : AF_UNSPEC;
1606 HT_INSERT(getaddrinfo_cache, &getaddrinfo_cache, item);
1609 if (item->res) {
1610 freeaddrinfo(item->res);
1611 item->res = NULL;
1613 item->res = *res;
1614 item->err = err;
1615 return err;
1618 /* Otherwise, the sanbox is on. If we have an item, yield its cached
1619 result. */
1620 if (item) {
1621 *res = item->res;
1622 return item->err;
1625 /* getting here means something went wrong */
1626 log_err(LD_BUG,"(Sandbox) failed to get address %s!", name);
1627 return EAI_NONAME;
1631 sandbox_add_addrinfo(const char *name)
1633 struct addrinfo *res;
1634 struct addrinfo hints;
1635 int i;
1636 static const int families[] = { AF_INET, AF_INET6, AF_UNSPEC };
1638 memset(&hints, 0, sizeof(hints));
1639 hints.ai_socktype = SOCK_STREAM;
1640 for (i = 0; i < 3; ++i) {
1641 hints.ai_family = families[i];
1643 res = NULL;
1644 (void) sandbox_getaddrinfo(name, NULL, &hints, &res);
1645 if (res)
1646 sandbox_freeaddrinfo(res);
1649 return 0;
1652 void
1653 sandbox_free_getaddrinfo_cache(void)
1655 cached_getaddrinfo_item_t **next, **item, *this;
1657 for (item = HT_START(getaddrinfo_cache, &getaddrinfo_cache);
1658 item;
1659 item = next) {
1660 this = *item;
1661 next = HT_NEXT_RMV(getaddrinfo_cache, &getaddrinfo_cache, item);
1662 cached_getaddrinfo_item_free(this);
1665 HT_CLEAR(getaddrinfo_cache, &getaddrinfo_cache);
1669 * Function responsible for going through the parameter syscall filters and
1670 * call each function pointer in the list.
1672 static int
1673 add_param_filter(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
1675 unsigned i;
1676 int rc = 0;
1678 // function pointer
1679 for (i = 0; i < ARRAY_LENGTH(filter_func); i++) {
1680 rc = filter_func[i](ctx, cfg);
1681 if (rc) {
1682 log_err(LD_BUG,"(Sandbox) failed to add syscall %d, received libseccomp "
1683 "error %d", i, rc);
1684 return rc;
1688 return 0;
1692 * Function responsible of loading the libseccomp syscall filters which do not
1693 * have parameter filtering.
1695 static int
1696 add_noparam_filter(scmp_filter_ctx ctx)
1698 unsigned i;
1699 int rc = 0;
1701 // add general filters
1702 for (i = 0; i < ARRAY_LENGTH(filter_nopar_gen); i++) {
1703 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i]);
1704 if (rc != 0) {
1705 log_err(LD_BUG,"(Sandbox) failed to add syscall index %d (NR=%d), "
1706 "received libseccomp error %d", i, filter_nopar_gen[i], rc);
1707 return rc;
1711 return 0;
1715 * Function responsible for setting up and enabling a global syscall filter.
1716 * The function is a prototype developed for stage 1 of sandboxing Tor.
1717 * Returns 0 on success.
1719 static int
1720 install_syscall_filter(sandbox_cfg_t* cfg)
1722 int rc = 0;
1723 scmp_filter_ctx ctx;
1725 ctx = seccomp_init(SCMP_ACT_TRAP);
1726 if (ctx == NULL) {
1727 log_err(LD_BUG,"(Sandbox) failed to initialise libseccomp context");
1728 rc = -1;
1729 goto end;
1732 // protectign sandbox parameter strings
1733 if ((rc = prot_strings(ctx, cfg))) {
1734 goto end;
1737 // add parameter filters
1738 if ((rc = add_param_filter(ctx, cfg))) {
1739 log_err(LD_BUG, "(Sandbox) failed to add param filters!");
1740 goto end;
1743 // adding filters with no parameters
1744 if ((rc = add_noparam_filter(ctx))) {
1745 log_err(LD_BUG, "(Sandbox) failed to add param filters!");
1746 goto end;
1749 // loading the seccomp2 filter
1750 if ((rc = seccomp_load(ctx))) {
1751 log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)!", rc,
1752 strerror(-rc));
1753 goto end;
1756 // marking the sandbox as active
1757 sandbox_active = 1;
1759 end:
1760 seccomp_release(ctx);
1761 return (rc < 0 ? -rc : rc);
1764 #include "linux_syscalls.inc"
1765 static const char *
1766 get_syscall_name(int syscall_num)
1768 int i;
1769 for (i = 0; SYSCALLS_BY_NUMBER[i].syscall_name; ++i) {
1770 if (SYSCALLS_BY_NUMBER[i].syscall_num == syscall_num)
1771 return SYSCALLS_BY_NUMBER[i].syscall_name;
1775 static char syscall_name_buf[64];
1776 format_dec_number_sigsafe(syscall_num,
1777 syscall_name_buf, sizeof(syscall_name_buf));
1778 return syscall_name_buf;
1782 #ifdef USE_BACKTRACE
1783 #define MAX_DEPTH 256
1784 static void *syscall_cb_buf[MAX_DEPTH];
1785 #endif
1788 * Function called when a SIGSYS is caught by the application. It notifies the
1789 * user that an error has occurred and either terminates or allows the
1790 * application to continue execution, based on the DEBUGGING_CLOSE symbol.
1792 static void
1793 sigsys_debugging(int nr, siginfo_t *info, void *void_context)
1795 ucontext_t *ctx = (ucontext_t *) (void_context);
1796 const char *syscall_name;
1797 int syscall;
1798 #ifdef USE_BACKTRACE
1799 size_t depth;
1800 int n_fds, i;
1801 const int *fds = NULL;
1802 #endif
1804 (void) nr;
1806 if (info->si_code != SYS_SECCOMP)
1807 return;
1809 if (!ctx)
1810 return;
1812 syscall = (int) ctx->uc_mcontext.M_SYSCALL;
1814 #ifdef USE_BACKTRACE
1815 depth = backtrace(syscall_cb_buf, MAX_DEPTH);
1816 /* Clean up the top stack frame so we get the real function
1817 * name for the most recently failing function. */
1818 clean_backtrace(syscall_cb_buf, depth, ctx);
1819 #endif
1821 syscall_name = get_syscall_name(syscall);
1823 tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
1824 syscall_name,
1825 ")\n",
1826 NULL);
1828 #ifdef USE_BACKTRACE
1829 n_fds = tor_log_get_sigsafe_err_fds(&fds);
1830 for (i=0; i < n_fds; ++i)
1831 backtrace_symbols_fd(syscall_cb_buf, (int)depth, fds[i]);
1832 #endif
1834 #if defined(DEBUGGING_CLOSE)
1835 _exit(1);
1836 #endif // DEBUGGING_CLOSE
1840 * Function that adds a handler for SIGSYS, which is the signal thrown
1841 * when the application is issuing a syscall which is not allowed. The
1842 * main purpose of this function is to help with debugging by identifying
1843 * filtered syscalls.
1845 static int
1846 install_sigsys_debugging(void)
1848 struct sigaction act;
1849 sigset_t mask;
1851 memset(&act, 0, sizeof(act));
1852 sigemptyset(&mask);
1853 sigaddset(&mask, SIGSYS);
1855 act.sa_sigaction = &sigsys_debugging;
1856 act.sa_flags = SA_SIGINFO;
1857 if (sigaction(SIGSYS, &act, NULL) < 0) {
1858 log_err(LD_BUG,"(Sandbox) Failed to register SIGSYS signal handler");
1859 return -1;
1862 if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
1863 log_err(LD_BUG,"(Sandbox) Failed call to sigprocmask()");
1864 return -2;
1867 return 0;
1871 * Function responsible of registering the sandbox_cfg_t list of parameter
1872 * syscall filters to the existing parameter list. This is used for incipient
1873 * multiple-sandbox support.
1875 static int
1876 register_cfg(sandbox_cfg_t* cfg)
1878 sandbox_cfg_t *elem = NULL;
1880 if (filter_dynamic == NULL) {
1881 filter_dynamic = cfg;
1882 return 0;
1885 for (elem = filter_dynamic; elem->next != NULL; elem = elem->next)
1888 elem->next = cfg;
1890 return 0;
1893 #endif // USE_LIBSECCOMP
1895 #ifdef USE_LIBSECCOMP
1897 * Initialises the syscall sandbox filter for any linux architecture, taking
1898 * into account various available features for different linux flavours.
1900 static int
1901 initialise_libseccomp_sandbox(sandbox_cfg_t* cfg)
1903 /* Prevent glibc from trying to open /dev/tty on fatal error */
1904 setenv("LIBC_FATAL_STDERR_", "1", 1);
1906 if (install_sigsys_debugging())
1907 return -1;
1909 if (install_syscall_filter(cfg))
1910 return -2;
1912 if (register_cfg(cfg))
1913 return -3;
1915 return 0;
1919 sandbox_is_active(void)
1921 return sandbox_active != 0;
1923 #endif // USE_LIBSECCOMP
1925 sandbox_cfg_t*
1926 sandbox_cfg_new(void)
1928 return NULL;
1932 sandbox_init(sandbox_cfg_t *cfg)
1934 #if defined(USE_LIBSECCOMP)
1935 return initialise_libseccomp_sandbox(cfg);
1937 #elif defined(__linux__)
1938 (void)cfg;
1939 log_warn(LD_GENERAL,
1940 "This version of Tor was built without support for sandboxing. To "
1941 "build with support for sandboxing on Linux, you must have "
1942 "libseccomp and its necessary header files (e.g. seccomp.h).");
1943 return 0;
1945 #else
1946 (void)cfg;
1947 log_warn(LD_GENERAL,
1948 "Currently, sandboxing is only implemented on Linux. The feature "
1949 "is disabled on your platform.");
1950 return 0;
1951 #endif
1954 #ifndef USE_LIBSECCOMP
1956 sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
1958 (void)cfg; (void)file;
1959 return 0;
1963 sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
1965 (void)cfg; (void)file;
1966 return 0;
1969 #if 0
1971 sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
1973 (void)cfg; (void)com;
1974 return 0;
1976 #endif
1979 sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
1981 (void)cfg; (void)file;
1982 return 0;
1986 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
1988 (void)cfg; (void)file;
1989 return 0;
1993 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
1995 (void)cfg; (void)file;
1996 return 0;
2000 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
2002 (void)cfg; (void)file1; (void)file2;
2003 return 0;
2007 sandbox_is_active(void)
2009 return 0;
2012 void
2013 sandbox_disable_getaddrinfo_cache(void)
2016 #endif