Tor  0.4.3.0-alpha-dev
sandbox.c
Go to the documentation of this file.
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-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 /**
8  * \file sandbox.c
9  * \brief Code to enable sandboxing.
10  **/
11 
12 #include "orconfig.h"
13 
14 #ifndef _LARGEFILE64_SOURCE
15 /**
16  * Temporarily required for O_LARGEFILE flag. Needs to be removed
17  * with the libevent fix.
18  */
19 #define _LARGEFILE64_SOURCE
20 #endif /* !defined(_LARGEFILE64_SOURCE) */
21 
22 /** Malloc mprotect limit in bytes.
23  *
24  * 28/06/2017: This value was increased from 16 MB to 20 MB after we introduced
25  * LZMA support in Tor (0.3.1.1-alpha). We limit our LZMA coder to 16 MB, but
26  * liblzma have a small overhead that we need to compensate for to avoid being
27  * killed by the sandbox.
28  */
29 #define MALLOC_MP_LIM (20*1024*1024)
30 
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 
36 #include "lib/sandbox/sandbox.h"
37 #include "lib/container/map.h"
38 #include "lib/err/torerr.h"
39 #include "lib/log/log.h"
40 #include "lib/cc/torint.h"
41 #include "lib/malloc/malloc.h"
42 #include "lib/string/scanf.h"
43 
44 #include "ext/tor_queue.h"
45 #include "ext/ht.h"
46 #include "ext/siphash.h"
47 
48 #define DEBUGGING_CLOSE
49 
50 #if defined(USE_LIBSECCOMP)
51 
52 #include <sys/mman.h>
53 #include <sys/syscall.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <sys/epoll.h>
57 #include <sys/prctl.h>
58 #include <linux/futex.h>
59 #include <sys/file.h>
60 
61 #include <stdarg.h>
62 #include <seccomp.h>
63 #include <signal.h>
64 #include <unistd.h>
65 #include <fcntl.h>
66 #include <time.h>
67 #include <poll.h>
68 
69 #ifdef HAVE_GNU_LIBC_VERSION_H
70 #include <gnu/libc-version.h>
71 #endif
72 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
73 #include <linux/netfilter_ipv4.h>
74 #endif
75 #ifdef HAVE_LINUX_IF_H
76 #include <linux/if.h>
77 #endif
78 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
79 #include <linux/netfilter_ipv6/ip6_tables.h>
80 #endif
81 
82 #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
83  defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
84 #define USE_BACKTRACE
85 #define EXPOSE_CLEAN_BACKTRACE
86 #include "lib/err/backtrace.h"
87 #endif /* defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && ... */
88 
89 #ifdef USE_BACKTRACE
90 #include <execinfo.h>
91 #endif
92 
93 /**
94  * Linux 32 bit definitions
95  */
96 #if defined(__i386__)
97 
98 #define REG_SYSCALL REG_EAX
99 #define M_SYSCALL gregs[REG_SYSCALL]
100 
101 /**
102  * Linux 64 bit definitions
103  */
104 #elif defined(__x86_64__)
105 
106 #define REG_SYSCALL REG_RAX
107 #define M_SYSCALL gregs[REG_SYSCALL]
108 
109 #elif defined(__arm__)
110 
111 #define M_SYSCALL arm_r7
112 
113 #elif defined(__aarch64__) && defined(__LP64__)
114 
115 #define REG_SYSCALL 8
116 #define M_SYSCALL regs[REG_SYSCALL]
117 
118 #endif /* defined(__i386__) || ... */
119 
120 /**Determines if at least one sandbox is active.*/
121 static int sandbox_active = 0;
122 /** Holds the parameter list configuration for the sandbox.*/
123 static sandbox_cfg_t *filter_dynamic = NULL;
124 
125 #undef SCMP_CMP
126 #define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0})
127 #define SCMP_CMP_STR(a,b,c) \
128  ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0})
129 #define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)})
130 /* We use a wrapper here because these masked comparisons seem to be pretty
131  * verbose. Also, it's important to cast to scmp_datum_t before negating the
132  * mask, since otherwise the negation might get applied to a 32 bit value, and
133  * the high bits of the value might get masked out improperly. */
134 #define SCMP_CMP_MASKED(a,b,c) \
135  SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c))
136 
137 /** Variable used for storing all syscall numbers that will be allowed with the
138  * stage 1 general Tor sandbox.
139  */
140 static int filter_nopar_gen[] = {
141  SCMP_SYS(access),
142  SCMP_SYS(brk),
143  SCMP_SYS(clock_gettime),
144  SCMP_SYS(close),
145  SCMP_SYS(clone),
146  SCMP_SYS(epoll_create),
147  SCMP_SYS(epoll_wait),
148 #ifdef __NR_epoll_pwait
149  SCMP_SYS(epoll_pwait),
150 #endif
151 #ifdef HAVE_EVENTFD
152  SCMP_SYS(eventfd2),
153 #endif
154 #ifdef HAVE_PIPE2
155  SCMP_SYS(pipe2),
156 #endif
157 #ifdef HAVE_PIPE
158  SCMP_SYS(pipe),
159 #endif
160 #ifdef __NR_fchmod
161  SCMP_SYS(fchmod),
162 #endif
163  SCMP_SYS(fcntl),
164  SCMP_SYS(fstat),
165 #ifdef __NR_fstat64
166  SCMP_SYS(fstat64),
167 #endif
168  SCMP_SYS(futex),
169  SCMP_SYS(getdents),
170  SCMP_SYS(getdents64),
171  SCMP_SYS(getegid),
172 #ifdef __NR_getegid32
173  SCMP_SYS(getegid32),
174 #endif
175  SCMP_SYS(geteuid),
176 #ifdef __NR_geteuid32
177  SCMP_SYS(geteuid32),
178 #endif
179  SCMP_SYS(getgid),
180 #ifdef __NR_getgid32
181  SCMP_SYS(getgid32),
182 #endif
183  SCMP_SYS(getpid),
184 #ifdef __NR_getrlimit
185  SCMP_SYS(getrlimit),
186 #endif
187  SCMP_SYS(gettimeofday),
188  SCMP_SYS(gettid),
189  SCMP_SYS(getuid),
190 #ifdef __NR_getuid32
191  SCMP_SYS(getuid32),
192 #endif
193  SCMP_SYS(lseek),
194 #ifdef __NR__llseek
195  SCMP_SYS(_llseek),
196 #endif
197  SCMP_SYS(mkdir),
198  SCMP_SYS(mlockall),
199 #ifdef __NR_mmap
200  /* XXXX restrict this in the same ways as mmap2 */
201  SCMP_SYS(mmap),
202 #endif
203  SCMP_SYS(munmap),
204 #ifdef __NR_nanosleep
205  SCMP_SYS(nanosleep),
206 #endif
207 #ifdef __NR_prlimit
208  SCMP_SYS(prlimit),
209 #endif
210 #ifdef __NR_prlimit64
211  SCMP_SYS(prlimit64),
212 #endif
213  SCMP_SYS(read),
214  SCMP_SYS(rt_sigreturn),
215  SCMP_SYS(sched_getaffinity),
216 #ifdef __NR_sched_yield
217  SCMP_SYS(sched_yield),
218 #endif
219  SCMP_SYS(sendmsg),
220  SCMP_SYS(set_robust_list),
221 #ifdef __NR_setrlimit
222  SCMP_SYS(setrlimit),
223 #endif
224  SCMP_SYS(shutdown),
225 #ifdef __NR_sigaltstack
226  SCMP_SYS(sigaltstack),
227 #endif
228 #ifdef __NR_sigreturn
229  SCMP_SYS(sigreturn),
230 #endif
231  SCMP_SYS(stat),
232  SCMP_SYS(uname),
233  SCMP_SYS(wait4),
234  SCMP_SYS(write),
235  SCMP_SYS(writev),
236  SCMP_SYS(exit_group),
237  SCMP_SYS(exit),
238 
239  SCMP_SYS(madvise),
240 #ifdef __NR_stat64
241  // getaddrinfo uses this..
242  SCMP_SYS(stat64),
243 #endif
244 
245 #ifdef __NR_getrandom
246  SCMP_SYS(getrandom),
247 #endif
248 
249 #ifdef __NR_sysinfo
250  // qsort uses this..
251  SCMP_SYS(sysinfo),
252 #endif
253  /*
254  * These socket syscalls are not required on x86_64 and not supported with
255  * some libseccomp versions (eg: 1.0.1)
256  */
257 #if defined(__i386)
258  SCMP_SYS(recv),
259  SCMP_SYS(send),
260 #endif
261 
262  // socket syscalls
263  SCMP_SYS(bind),
264  SCMP_SYS(listen),
265  SCMP_SYS(connect),
266  SCMP_SYS(getsockname),
267  SCMP_SYS(recvmsg),
268  SCMP_SYS(recvfrom),
269  SCMP_SYS(sendto),
270  SCMP_SYS(unlink),
271  SCMP_SYS(poll)
272 };
273 
274 /* These macros help avoid the error where the number of filters we add on a
275  * single rule don't match the arg_cnt param. */
276 #define seccomp_rule_add_0(ctx,act,call) \
277  seccomp_rule_add((ctx),(act),(call),0)
278 #define seccomp_rule_add_1(ctx,act,call,f1) \
279  seccomp_rule_add((ctx),(act),(call),1,(f1))
280 #define seccomp_rule_add_2(ctx,act,call,f1,f2) \
281  seccomp_rule_add((ctx),(act),(call),2,(f1),(f2))
282 #define seccomp_rule_add_3(ctx,act,call,f1,f2,f3) \
283  seccomp_rule_add((ctx),(act),(call),3,(f1),(f2),(f3))
284 #define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \
285  seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4))
286 
287 /**
288  * Function responsible for setting up the rt_sigaction syscall for
289  * the seccomp filter sandbox.
290  */
291 static int
292 sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
293 {
294  unsigned i;
295  int rc;
296  int param[] = { SIGINT, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, SIGHUP, SIGCHLD,
297  SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, SIGIO,
298 #ifdef SIGXFSZ
299  SIGXFSZ
300 #endif
301  };
302  (void) filter;
303 
304  for (i = 0; i < ARRAY_LENGTH(param); i++) {
305  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction),
306  SCMP_CMP(0, SCMP_CMP_EQ, param[i]));
307  if (rc)
308  break;
309  }
310 
311  return rc;
312 }
313 
314 /**
315  * Function responsible for setting up the time syscall for
316  * the seccomp filter sandbox.
317  */
318 static int
319 sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
320 {
321  (void) filter;
322 #ifdef __NR_time
323  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time),
324  SCMP_CMP(0, SCMP_CMP_EQ, 0));
325 #else
326  return 0;
327 #endif /* defined(__NR_time) */
328 }
329 
330 /**
331  * Function responsible for setting up the accept4 syscall for
332  * the seccomp filter sandbox.
333  */
334 static int
335 sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
336 {
337  int rc = 0;
338  (void)filter;
339 
340 #ifdef __i386__
341  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall),
342  SCMP_CMP(0, SCMP_CMP_EQ, 18));
343  if (rc) {
344  return rc;
345  }
346 #endif /* defined(__i386__) */
347 
348  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4),
349  SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0));
350  if (rc) {
351  return rc;
352  }
353 
354  return 0;
355 }
356 
357 #ifdef __NR_mmap2
358 /**
359  * Function responsible for setting up the mmap2 syscall for
360  * the seccomp filter sandbox.
361  */
362 static int
363 sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
364 {
365  int rc = 0;
366  (void)filter;
367 
368  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
369  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ),
370  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE));
371  if (rc) {
372  return rc;
373  }
374 
375  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
376  SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE),
377  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE));
378  if (rc) {
379  return rc;
380  }
381 
382  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
383  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
384  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS));
385  if (rc) {
386  return rc;
387  }
388 
389  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
390  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
391  SCMP_CMP(3, SCMP_CMP_EQ,MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK));
392  if (rc) {
393  return rc;
394  }
395 
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_FIXED|MAP_DENYWRITE));
399  if (rc) {
400  return rc;
401  }
402 
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_FIXED|MAP_ANONYMOUS));
406  if (rc) {
407  return rc;
408  }
409 
410  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
411  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_EXEC),
412  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_DENYWRITE));
413  if (rc) {
414  return rc;
415  }
416 
417  return 0;
418 }
419 #endif /* defined(__NR_mmap2) */
420 
421 #ifdef HAVE_GNU_LIBC_VERSION_H
422 #ifdef HAVE_GNU_GET_LIBC_VERSION
423 #define CHECK_LIBC_VERSION
424 #endif
425 #endif
426 
427 /* Return true if we think we're running with a libc that always uses
428  * openat on linux. */
429 static int
430 libc_uses_openat_for_everything(void)
431 {
432 #ifdef CHECK_LIBC_VERSION
433  const char *version = gnu_get_libc_version();
434  if (version == NULL)
435  return 0;
436 
437  int major = -1;
438  int minor = -1;
439 
440  tor_sscanf(version, "%d.%d", &major, &minor);
441  if (major >= 3)
442  return 1;
443  else if (major == 2 && minor >= 26)
444  return 1;
445  else
446  return 0;
447 #else /* !defined(CHECK_LIBC_VERSION) */
448  return 0;
449 #endif /* defined(CHECK_LIBC_VERSION) */
450 }
451 
452 /** Allow a single file to be opened. If <b>use_openat</b> is true,
453  * we're using a libc that remaps all the opens into openats. */
454 static int
455 allow_file_open(scmp_filter_ctx ctx, int use_openat, const char *file)
456 {
457  if (use_openat) {
458  return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
459  SCMP_CMP(0, SCMP_CMP_EQ, (unsigned int)AT_FDCWD),
460  SCMP_CMP_STR(1, SCMP_CMP_EQ, file));
461  } else {
462  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),
463  SCMP_CMP_STR(0, SCMP_CMP_EQ, file));
464  }
465 }
466 
467 /**
468  * Function responsible for setting up the open syscall for
469  * the seccomp filter sandbox.
470  */
471 static int
472 sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
473 {
474  int rc;
475  sandbox_cfg_t *elem = NULL;
476 
477  int use_openat = libc_uses_openat_for_everything();
478 
479  // for each dynamic parameter filters
480  for (elem = filter; elem != NULL; elem = elem->next) {
481  smp_param_t *param = elem->param;
482 
483  if (param != NULL && param->prot == 1 && param->syscall
484  == SCMP_SYS(open)) {
485  rc = allow_file_open(ctx, use_openat, param->value);
486  if (rc != 0) {
487  log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
488  "libseccomp error %d", rc);
489  return rc;
490  }
491  }
492  }
493 
494  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open),
495  SCMP_CMP_MASKED(1, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW,
496  O_RDONLY));
497  if (rc != 0) {
498  log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp "
499  "error %d", rc);
500  return rc;
501  }
502 
503  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(openat),
504  SCMP_CMP_MASKED(2, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW,
505  O_RDONLY));
506  if (rc != 0) {
507  log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
508  "libseccomp error %d", rc);
509  return rc;
510  }
511 
512  return 0;
513 }
514 
515 static int
516 sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
517 {
518  int rc;
519  sandbox_cfg_t *elem = NULL;
520 
521  // for each dynamic parameter filters
522  for (elem = filter; elem != NULL; elem = elem->next) {
523  smp_param_t *param = elem->param;
524 
525  if (param != NULL && param->prot == 1 && param->syscall
526  == SCMP_SYS(chmod)) {
527  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod),
528  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
529  if (rc != 0) {
530  log_err(LD_BUG,"(Sandbox) failed to add chmod syscall, received "
531  "libseccomp error %d", rc);
532  return rc;
533  }
534  }
535  }
536 
537  return 0;
538 }
539 
540 static int
541 sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
542 {
543  int rc;
544  sandbox_cfg_t *elem = NULL;
545 
546  // for each dynamic parameter filters
547  for (elem = filter; elem != NULL; elem = elem->next) {
548  smp_param_t *param = elem->param;
549 
550  if (param != NULL && param->prot == 1 && param->syscall
551  == SCMP_SYS(chown)) {
552  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown),
553  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
554  if (rc != 0) {
555  log_err(LD_BUG,"(Sandbox) failed to add chown syscall, received "
556  "libseccomp error %d", rc);
557  return rc;
558  }
559  }
560  }
561 
562  return 0;
563 }
564 
565 static int
566 sb__sysctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
567 {
568  int rc;
569  (void) filter;
570  (void) ctx;
571 
572  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(_sysctl));
573  if (rc != 0) {
574  log_err(LD_BUG,"(Sandbox) failed to add _sysctl syscall, "
575  "received libseccomp error %d", rc);
576  return rc;
577  }
578 
579  return 0;
580 }
581 
582 /**
583  * Function responsible for setting up the rename syscall for
584  * the seccomp filter sandbox.
585  */
586 static int
587 sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
588 {
589  int rc;
590  sandbox_cfg_t *elem = NULL;
591 
592  // for each dynamic parameter filters
593  for (elem = filter; elem != NULL; elem = elem->next) {
594  smp_param_t *param = elem->param;
595 
596  if (param != NULL && param->prot == 1 &&
597  param->syscall == SCMP_SYS(rename)) {
598 
599  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename),
600  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value),
601  SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2));
602  if (rc != 0) {
603  log_err(LD_BUG,"(Sandbox) failed to add rename syscall, received "
604  "libseccomp error %d", rc);
605  return rc;
606  }
607  }
608  }
609 
610  return 0;
611 }
612 
613 /**
614  * Function responsible for setting up the openat syscall for
615  * the seccomp filter sandbox.
616  */
617 static int
618 sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
619 {
620  int rc;
621  sandbox_cfg_t *elem = NULL;
622 
623  // for each dynamic parameter filters
624  for (elem = filter; elem != NULL; elem = elem->next) {
625  smp_param_t *param = elem->param;
626 
627  if (param != NULL && param->prot == 1 && param->syscall
628  == SCMP_SYS(openat)) {
629  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
630  SCMP_CMP(0, SCMP_CMP_EQ, AT_FDCWD),
631  SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
632  SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
633  O_CLOEXEC));
634  if (rc != 0) {
635  log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
636  "libseccomp error %d", rc);
637  return rc;
638  }
639  }
640  }
641 
642  return 0;
643 }
644 
645 /**
646  * Function responsible for setting up the socket syscall for
647  * the seccomp filter sandbox.
648  */
649 static int
650 sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
651 {
652  int rc = 0;
653  int i, j;
654  (void) filter;
655 
656 #ifdef __i386__
657  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket));
658  if (rc)
659  return rc;
660 #endif
661 
662  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
663  SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
664  SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM));
665  if (rc)
666  return rc;
667 
668  for (i = 0; i < 2; ++i) {
669  const int pf = i ? PF_INET : PF_INET6;
670  for (j=0; j < 3; ++j) {
671  const int type = (j == 0) ? SOCK_STREAM :
672  SOCK_DGRAM;
673  const int protocol = (j == 0) ? IPPROTO_TCP :
674  (j == 1) ? IPPROTO_IP :
675  IPPROTO_UDP;
676  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
677  SCMP_CMP(0, SCMP_CMP_EQ, pf),
678  SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, type),
679  SCMP_CMP(2, SCMP_CMP_EQ, protocol));
680  if (rc)
681  return rc;
682  }
683  }
684 
685  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
686  SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
687  SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM),
688  SCMP_CMP(2, SCMP_CMP_EQ, 0));
689  if (rc)
690  return rc;
691 
692  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
693  SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
694  SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_DGRAM),
695  SCMP_CMP(2, SCMP_CMP_EQ, 0));
696  if (rc)
697  return rc;
698 
699  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
700  SCMP_CMP(0, SCMP_CMP_EQ, PF_NETLINK),
701  SCMP_CMP_MASKED(1, SOCK_CLOEXEC, SOCK_RAW),
702  SCMP_CMP(2, SCMP_CMP_EQ, 0));
703  if (rc)
704  return rc;
705 
706  return 0;
707 }
708 
709 /**
710  * Function responsible for setting up the socketpair syscall for
711  * the seccomp filter sandbox.
712  */
713 static int
714 sb_socketpair(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
715 {
716  int rc = 0;
717  (void) filter;
718 
719 #ifdef __i386__
720  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair));
721  if (rc)
722  return rc;
723 #endif
724 
725  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair),
726  SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
727  SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC));
728  if (rc)
729  return rc;
730 
731  return 0;
732 }
733 
734 #ifdef HAVE_KIST_SUPPORT
735 
736 #include <linux/sockios.h>
737 
738 static int
739 sb_ioctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
740 {
741  int rc;
742  (void) filter;
743 
744  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl),
745  SCMP_CMP(1, SCMP_CMP_EQ, SIOCOUTQNSD));
746  if (rc)
747  return rc;
748  return 0;
749 }
750 
751 #endif /* defined(HAVE_KIST_SUPPORT) */
752 
753 /**
754  * Function responsible for setting up the setsockopt syscall for
755  * the seccomp filter sandbox.
756  */
757 static int
758 sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
759 {
760  int rc = 0;
761  (void) filter;
762 
763 #ifdef __i386__
764  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt));
765  if (rc)
766  return rc;
767 #endif
768 
769  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
770  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
771  SCMP_CMP(2, SCMP_CMP_EQ, SO_REUSEADDR));
772  if (rc)
773  return rc;
774 
775  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
776  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
777  SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
778  if (rc)
779  return rc;
780 
781  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
782  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
783  SCMP_CMP(2, SCMP_CMP_EQ, SO_RCVBUF));
784  if (rc)
785  return rc;
786 
787 #ifdef HAVE_SYSTEMD
788  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
789  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
790  SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUFFORCE));
791  if (rc)
792  return rc;
793 #endif /* defined(HAVE_SYSTEMD) */
794 
795 #ifdef IP_TRANSPARENT
796  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
797  SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
798  SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT));
799  if (rc)
800  return rc;
801 #endif /* defined(IP_TRANSPARENT) */
802 
803 #ifdef IPV6_V6ONLY
804  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
805  SCMP_CMP(1, SCMP_CMP_EQ, IPPROTO_IPV6),
806  SCMP_CMP(2, SCMP_CMP_EQ, IPV6_V6ONLY));
807  if (rc)
808  return rc;
809 #endif /* defined(IPV6_V6ONLY) */
810 
811  return 0;
812 }
813 
814 /**
815  * Function responsible for setting up the getsockopt syscall for
816  * the seccomp filter sandbox.
817  */
818 static int
819 sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
820 {
821  int rc = 0;
822  (void) filter;
823 
824 #ifdef __i386__
825  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt));
826  if (rc)
827  return rc;
828 #endif
829 
830  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
831  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
832  SCMP_CMP(2, SCMP_CMP_EQ, SO_ERROR));
833  if (rc)
834  return rc;
835 
836  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
837  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
838  SCMP_CMP(2, SCMP_CMP_EQ, SO_ACCEPTCONN));
839  if (rc)
840  return rc;
841 
842 #ifdef HAVE_SYSTEMD
843  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
844  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
845  SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
846  if (rc)
847  return rc;
848 #endif /* defined(HAVE_SYSTEMD) */
849 
850 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
851  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
852  SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
853  SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST));
854  if (rc)
855  return rc;
856 #endif /* defined(HAVE_LINUX_NETFILTER_IPV4_H) */
857 
858 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
859  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
860  SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6),
861  SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST));
862  if (rc)
863  return rc;
864 #endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */
865 
866 #ifdef HAVE_KIST_SUPPORT
867 #include <netinet/tcp.h>
868  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
869  SCMP_CMP(1, SCMP_CMP_EQ, SOL_TCP),
870  SCMP_CMP(2, SCMP_CMP_EQ, TCP_INFO));
871  if (rc)
872  return rc;
873 #endif /* defined(HAVE_KIST_SUPPORT) */
874 
875  return 0;
876 }
877 
878 #ifdef __NR_fcntl64
879 /**
880  * Function responsible for setting up the fcntl64 syscall for
881  * the seccomp filter sandbox.
882  */
883 static int
884 sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
885 {
886  int rc = 0;
887  (void) filter;
888 
889  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
890  SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL));
891  if (rc)
892  return rc;
893 
894  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
895  SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL),
896  SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK));
897  if (rc)
898  return rc;
899 
900  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
901  SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD));
902  if (rc)
903  return rc;
904 
905  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
906  SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD),
907  SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC));
908  if (rc)
909  return rc;
910 
911  return 0;
912 }
913 #endif /* defined(__NR_fcntl64) */
914 
915 /**
916  * Function responsible for setting up the epoll_ctl syscall for
917  * the seccomp filter sandbox.
918  *
919  * Note: basically allows everything but will keep for now..
920  */
921 static int
922 sb_epoll_ctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
923 {
924  int rc = 0;
925  (void) filter;
926 
927  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
928  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD));
929  if (rc)
930  return rc;
931 
932  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
933  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD));
934  if (rc)
935  return rc;
936 
937  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
938  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL));
939  if (rc)
940  return rc;
941 
942  return 0;
943 }
944 
945 /**
946  * Function responsible for setting up the prctl syscall for
947  * the seccomp filter sandbox.
948  *
949  * NOTE: if multiple filters need to be added, the PR_SECCOMP parameter needs
950  * to be whitelisted in this function.
951  */
952 static int
953 sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
954 {
955  int rc = 0;
956  (void) filter;
957 
958  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
959  SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE));
960  if (rc)
961  return rc;
962 
963  return 0;
964 }
965 
966 /**
967  * Function responsible for setting up the mprotect syscall for
968  * the seccomp filter sandbox.
969  *
970  * NOTE: does not NEED to be here.. currently only occurs before filter; will
971  * keep just in case for the future.
972  */
973 static int
974 sb_mprotect(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
975 {
976  int rc = 0;
977  (void) filter;
978 
979  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
980  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ));
981  if (rc)
982  return rc;
983 
984  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
985  SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE));
986  if (rc)
987  return rc;
988 
989  return 0;
990 }
991 
992 /**
993  * Function responsible for setting up the rt_sigprocmask syscall for
994  * the seccomp filter sandbox.
995  */
996 static int
997 sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
998 {
999  int rc = 0;
1000  (void) filter;
1001 
1002  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
1003  SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK));
1004  if (rc)
1005  return rc;
1006 
1007  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
1008  SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK));
1009  if (rc)
1010  return rc;
1011 
1012  return 0;
1013 }
1014 
1015 /**
1016  * Function responsible for setting up the flock syscall for
1017  * the seccomp filter sandbox.
1018  *
1019  * NOTE: does not need to be here, occurs before filter is applied.
1020  */
1021 static int
1022 sb_flock(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1023 {
1024  int rc = 0;
1025  (void) filter;
1026 
1027  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1028  SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB));
1029  if (rc)
1030  return rc;
1031 
1032  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1033  SCMP_CMP(1, SCMP_CMP_EQ, LOCK_UN));
1034  if (rc)
1035  return rc;
1036 
1037  return 0;
1038 }
1039 
1040 /**
1041  * Function responsible for setting up the futex syscall for
1042  * the seccomp filter sandbox.
1043  */
1044 static int
1045 sb_futex(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1046 {
1047  int rc = 0;
1048  (void) filter;
1049 
1050  // can remove
1051  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1052  SCMP_CMP(1, SCMP_CMP_EQ,
1053  FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME));
1054  if (rc)
1055  return rc;
1056 
1057  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1058  SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
1059  if (rc)
1060  return rc;
1061 
1062  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1063  SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE));
1064  if (rc)
1065  return rc;
1066 
1067  return 0;
1068 }
1069 
1070 /**
1071  * Function responsible for setting up the mremap syscall for
1072  * the seccomp filter sandbox.
1073  *
1074  * NOTE: so far only occurs before filter is applied.
1075  */
1076 static int
1077 sb_mremap(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1078 {
1079  int rc = 0;
1080  (void) filter;
1081 
1082  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap),
1083  SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE));
1084  if (rc)
1085  return rc;
1086 
1087  return 0;
1088 }
1089 
1090 #ifdef __NR_stat64
1091 /**
1092  * Function responsible for setting up the stat64 syscall for
1093  * the seccomp filter sandbox.
1094  */
1095 static int
1096 sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1097 {
1098  int rc = 0;
1099  sandbox_cfg_t *elem = NULL;
1100 
1101  // for each dynamic parameter filters
1102  for (elem = filter; elem != NULL; elem = elem->next) {
1103  smp_param_t *param = elem->param;
1104 
1105  if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
1106  || param->syscall == SCMP_SYS(stat64))) {
1107  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64),
1108  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
1109  if (rc != 0) {
1110  log_err(LD_BUG,"(Sandbox) failed to add stat64 syscall, received "
1111  "libseccomp error %d", rc);
1112  return rc;
1113  }
1114  }
1115  }
1116 
1117  return 0;
1118 }
1119 #endif /* defined(__NR_stat64) */
1120 
1121 static int
1122 sb_kill(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1123 {
1124  (void) filter;
1125 #ifdef __NR_kill
1126  /* Allow killing anything with signal 0 -- it isn't really a kill. */
1127  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(kill),
1128  SCMP_CMP(1, SCMP_CMP_EQ, 0));
1129 #else
1130  return 0;
1131 #endif /* defined(__NR_kill) */
1132 }
1133 
1134 /**
1135  * Array of function pointers responsible for filtering different syscalls at
1136  * a parameter level.
1137  */
1138 static sandbox_filter_func_t filter_func[] = {
1139  sb_rt_sigaction,
1140  sb_rt_sigprocmask,
1141  sb_time,
1142  sb_accept4,
1143 #ifdef __NR_mmap2
1144  sb_mmap2,
1145 #endif
1146  sb_chown,
1147  sb_chmod,
1148  sb_open,
1149  sb_openat,
1150  sb__sysctl,
1151  sb_rename,
1152 #ifdef __NR_fcntl64
1153  sb_fcntl64,
1154 #endif
1155  sb_epoll_ctl,
1156  sb_prctl,
1157  sb_mprotect,
1158  sb_flock,
1159  sb_futex,
1160  sb_mremap,
1161 #ifdef __NR_stat64
1162  sb_stat64,
1163 #endif
1164 
1165  sb_socket,
1166  sb_setsockopt,
1167  sb_getsockopt,
1168  sb_socketpair,
1169 #ifdef HAVE_KIST_SUPPORT
1170  sb_ioctl,
1171 #endif
1172  sb_kill
1173 };
1174 
1175 const char *
1176 sandbox_intern_string(const char *str)
1177 {
1178  sandbox_cfg_t *elem;
1179 
1180  if (str == NULL)
1181  return NULL;
1182 
1183  for (elem = filter_dynamic; elem != NULL; elem = elem->next) {
1184  smp_param_t *param = elem->param;
1185 
1186  if (param->prot) {
1187  if (!strcmp(str, (char*)(param->value))) {
1188  return (char*)param->value;
1189  }
1190  if (param->value2 && !strcmp(str, (char*)param->value2)) {
1191  return (char*)param->value2;
1192  }
1193  }
1194  }
1195 
1196  if (sandbox_active)
1197  log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
1198  return str;
1199 }
1200 
1201 /* DOCDOC */
1202 static int
1203 prot_strings_helper(strmap_t *locations,
1204  char **pr_mem_next_p,
1205  size_t *pr_mem_left_p,
1206  char **value_p)
1207 {
1208  char *param_val;
1209  size_t param_size;
1210  void *location;
1211 
1212  if (*value_p == 0)
1213  return 0;
1214 
1215  param_val = (char*) *value_p;
1216  param_size = strlen(param_val) + 1;
1217  location = strmap_get(locations, param_val);
1218 
1219  if (location) {
1220  // We already interned this string.
1221  tor_free(param_val);
1222  *value_p = location;
1223  return 0;
1224  } else if (*pr_mem_left_p >= param_size) {
1225  // copy to protected
1226  location = *pr_mem_next_p;
1227  memcpy(location, param_val, param_size);
1228 
1229  // re-point el parameter to protected
1230  tor_free(param_val);
1231  *value_p = location;
1232 
1233  strmap_set(locations, location, location); /* good real estate advice */
1234 
1235  // move next available protected memory
1236  *pr_mem_next_p += param_size;
1237  *pr_mem_left_p -= param_size;
1238  return 0;
1239  } else {
1240  log_err(LD_BUG,"(Sandbox) insufficient protected memory!");
1241  return -1;
1242  }
1243 }
1244 
1245 /**
1246  * Protects all the strings in the sandbox's parameter list configuration. It
1247  * works by calculating the total amount of memory required by the parameter
1248  * list, allocating the memory using mmap, and protecting it from writes with
1249  * mprotect().
1250  */
1251 static int
1252 prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
1253 {
1254  int ret = 0;
1255  size_t pr_mem_size = 0, pr_mem_left = 0;
1256  char *pr_mem_next = NULL, *pr_mem_base;
1257  sandbox_cfg_t *el = NULL;
1258  strmap_t *locations = NULL;
1259 
1260  // get total number of bytes required to mmap. (Overestimate.)
1261  for (el = cfg; el != NULL; el = el->next) {
1262  pr_mem_size += strlen((char*) el->param->value) + 1;
1263  if (el->param->value2)
1264  pr_mem_size += strlen((char*) el->param->value2) + 1;
1265  }
1266 
1267  // allocate protected memory with MALLOC_MP_LIM canary
1268  pr_mem_base = (char*) mmap(NULL, MALLOC_MP_LIM + pr_mem_size,
1269  PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
1270  if (pr_mem_base == MAP_FAILED) {
1271  log_err(LD_BUG,"(Sandbox) failed allocate protected memory! mmap: %s",
1272  strerror(errno));
1273  ret = -1;
1274  goto out;
1275  }
1276 
1277  pr_mem_next = pr_mem_base + MALLOC_MP_LIM;
1278  pr_mem_left = pr_mem_size;
1279 
1280  locations = strmap_new();
1281 
1282  // change el value pointer to protected
1283  for (el = cfg; el != NULL; el = el->next) {
1284  if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1285  &el->param->value) < 0) {
1286  ret = -2;
1287  goto out;
1288  }
1289  if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1290  &el->param->value2) < 0) {
1291  ret = -2;
1292  goto out;
1293  }
1294  el->param->prot = 1;
1295  }
1296 
1297  // protecting from writes
1298  if (mprotect(pr_mem_base, MALLOC_MP_LIM + pr_mem_size, PROT_READ)) {
1299  log_err(LD_BUG,"(Sandbox) failed to protect memory! mprotect: %s",
1300  strerror(errno));
1301  ret = -3;
1302  goto out;
1303  }
1304 
1305  /*
1306  * Setting sandbox restrictions so the string memory cannot be tampered with
1307  */
1308  // no mremap of the protected base address
1309  ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(mremap),
1310  SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1311  if (ret) {
1312  log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!");
1313  goto out;
1314  }
1315 
1316  // no munmap of the protected base address
1317  ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(munmap),
1318  SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1319  if (ret) {
1320  log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!");
1321  goto out;
1322  }
1323 
1324  /*
1325  * Allow mprotect with PROT_READ|PROT_WRITE because openssl uses it, but
1326  * never over the memory region used by the protected strings.
1327  *
1328  * PROT_READ|PROT_WRITE was originally fully allowed in sb_mprotect(), but
1329  * had to be removed due to limitation of libseccomp regarding intervals.
1330  *
1331  * There is a restriction on how much you can mprotect with R|W up to the
1332  * size of the canary.
1333  */
1334  ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1335  SCMP_CMP(0, SCMP_CMP_LT, (intptr_t) pr_mem_base),
1336  SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
1337  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1338  if (ret) {
1339  log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!");
1340  goto out;
1341  }
1342 
1343  ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1344  SCMP_CMP(0, SCMP_CMP_GT, (intptr_t) pr_mem_base + pr_mem_size +
1345  MALLOC_MP_LIM),
1346  SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
1347  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1348  if (ret) {
1349  log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!");
1350  goto out;
1351  }
1352 
1353  out:
1354  strmap_free(locations, NULL);
1355  return ret;
1356 }
1357 
1358 /**
1359  * Auxiliary function used in order to allocate a sandbox_cfg_t element and set
1360  * its values according the parameter list. All elements are initialised
1361  * with the 'prot' field set to false, as the pointer is not protected at this
1362  * point.
1363  */
1364 static sandbox_cfg_t*
1365 new_element2(int syscall, char *value, char *value2)
1366 {
1367  smp_param_t *param = NULL;
1368 
1369  sandbox_cfg_t *elem = tor_malloc_zero(sizeof(sandbox_cfg_t));
1370  param = elem->param = tor_malloc_zero(sizeof(smp_param_t));
1371 
1372  param->syscall = syscall;
1373  param->value = value;
1374  param->value2 = value2;
1375  param->prot = 0;
1376 
1377  return elem;
1378 }
1379 
1380 static sandbox_cfg_t*
1381 new_element(int syscall, char *value)
1382 {
1383  return new_element2(syscall, value, NULL);
1384 }
1385 
1386 #ifdef __NR_stat64
1387 #define SCMP_stat SCMP_SYS(stat64)
1388 #else
1389 #define SCMP_stat SCMP_SYS(stat)
1390 #endif
1391 
1392 int
1394 {
1395  sandbox_cfg_t *elem = NULL;
1396 
1397  elem = new_element(SCMP_stat, file);
1398 
1399  elem->next = *cfg;
1400  *cfg = elem;
1401 
1402  return 0;
1403 }
1404 
1405 int
1407 {
1408  sandbox_cfg_t *elem = NULL;
1409 
1410  elem = new_element(SCMP_SYS(open), file);
1411 
1412  elem->next = *cfg;
1413  *cfg = elem;
1414 
1415  return 0;
1416 }
1417 
1418 int
1419 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
1420 {
1421  sandbox_cfg_t *elem = NULL;
1422 
1423  elem = new_element(SCMP_SYS(chmod), file);
1424 
1425  elem->next = *cfg;
1426  *cfg = elem;
1427 
1428  return 0;
1429 }
1430 
1431 int
1432 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
1433 {
1434  sandbox_cfg_t *elem = NULL;
1435 
1436  elem = new_element(SCMP_SYS(chown), file);
1437 
1438  elem->next = *cfg;
1439  *cfg = elem;
1440 
1441  return 0;
1442 }
1443 
1444 int
1445 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
1446 {
1447  sandbox_cfg_t *elem = NULL;
1448 
1449  elem = new_element2(SCMP_SYS(rename), file1, file2);
1450 
1451  elem->next = *cfg;
1452  *cfg = elem;
1453 
1454  return 0;
1455 }
1456 
1457 int
1459 {
1460  sandbox_cfg_t *elem = NULL;
1461 
1462  elem = new_element(SCMP_SYS(openat), file);
1463 
1464  elem->next = *cfg;
1465  *cfg = elem;
1466 
1467  return 0;
1468 }
1469 
1470 /**
1471  * Function responsible for going through the parameter syscall filters and
1472  * call each function pointer in the list.
1473  */
1474 static int
1475 add_param_filter(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
1476 {
1477  unsigned i;
1478  int rc = 0;
1479 
1480  // function pointer
1481  for (i = 0; i < ARRAY_LENGTH(filter_func); i++) {
1482  rc = filter_func[i](ctx, cfg);
1483  if (rc) {
1484  log_err(LD_BUG,"(Sandbox) failed to add syscall %d, received libseccomp "
1485  "error %d", i, rc);
1486  return rc;
1487  }
1488  }
1489 
1490  return 0;
1491 }
1492 
1493 /**
1494  * Function responsible of loading the libseccomp syscall filters which do not
1495  * have parameter filtering.
1496  */
1497 static int
1498 add_noparam_filter(scmp_filter_ctx ctx)
1499 {
1500  unsigned i;
1501  int rc = 0;
1502 
1503  // add general filters
1504  for (i = 0; i < ARRAY_LENGTH(filter_nopar_gen); i++) {
1505  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i]);
1506  if (rc != 0) {
1507  log_err(LD_BUG,"(Sandbox) failed to add syscall index %d (NR=%d), "
1508  "received libseccomp error %d", i, filter_nopar_gen[i], rc);
1509  return rc;
1510  }
1511  }
1512 
1513  return 0;
1514 }
1515 
1516 /**
1517  * Function responsible for setting up and enabling a global syscall filter.
1518  * The function is a prototype developed for stage 1 of sandboxing Tor.
1519  * Returns 0 on success.
1520  */
1521 static int
1522 install_syscall_filter(sandbox_cfg_t* cfg)
1523 {
1524  int rc = 0;
1525  scmp_filter_ctx ctx;
1526 
1527  ctx = seccomp_init(SCMP_ACT_TRAP);
1528  if (ctx == NULL) {
1529  log_err(LD_BUG,"(Sandbox) failed to initialise libseccomp context");
1530  rc = -1;
1531  goto end;
1532  }
1533 
1534  // protectign sandbox parameter strings
1535  if ((rc = prot_strings(ctx, cfg))) {
1536  goto end;
1537  }
1538 
1539  // add parameter filters
1540  if ((rc = add_param_filter(ctx, cfg))) {
1541  log_err(LD_BUG, "(Sandbox) failed to add param filters!");
1542  goto end;
1543  }
1544 
1545  // adding filters with no parameters
1546  if ((rc = add_noparam_filter(ctx))) {
1547  log_err(LD_BUG, "(Sandbox) failed to add param filters!");
1548  goto end;
1549  }
1550 
1551  // loading the seccomp2 filter
1552  if ((rc = seccomp_load(ctx))) {
1553  log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)! "
1554  "Are you sure that your kernel has seccomp2 support? The "
1555  "sandbox won't work without it.", rc,
1556  strerror(-rc));
1557  goto end;
1558  }
1559 
1560  // marking the sandbox as active
1561  sandbox_active = 1;
1562 
1563  end:
1564  seccomp_release(ctx);
1565  return (rc < 0 ? -rc : rc);
1566 }
1567 
1568 #include "lib/sandbox/linux_syscalls.inc"
1569 
1570 static const char *
1571 get_syscall_name(int syscall_num)
1572 {
1573  int i;
1574  for (i = 0; SYSCALLS_BY_NUMBER[i].syscall_name; ++i) {
1575  if (SYSCALLS_BY_NUMBER[i].syscall_num == syscall_num)
1576  return SYSCALLS_BY_NUMBER[i].syscall_name;
1577  }
1578 
1579  {
1580  static char syscall_name_buf[64];
1581  format_dec_number_sigsafe(syscall_num,
1582  syscall_name_buf, sizeof(syscall_name_buf));
1583  return syscall_name_buf;
1584  }
1585 }
1586 
1587 #ifdef USE_BACKTRACE
1588 #define MAX_DEPTH 256
1589 static void *syscall_cb_buf[MAX_DEPTH];
1590 #endif
1591 
1592 /**
1593  * Function called when a SIGSYS is caught by the application. It notifies the
1594  * user that an error has occurred and either terminates or allows the
1595  * application to continue execution, based on the DEBUGGING_CLOSE symbol.
1596  */
1597 static void
1598 sigsys_debugging(int nr, siginfo_t *info, void *void_context)
1599 {
1600  ucontext_t *ctx = (ucontext_t *) (void_context);
1601  const char *syscall_name;
1602  int syscall;
1603 #ifdef USE_BACKTRACE
1604  size_t depth;
1605  int n_fds, i;
1606  const int *fds = NULL;
1607 #endif
1608 
1609  (void) nr;
1610 
1611  if (info->si_code != SYS_SECCOMP)
1612  return;
1613 
1614  if (!ctx)
1615  return;
1616 
1617  syscall = (int) ctx->uc_mcontext.M_SYSCALL;
1618 
1619 #ifdef USE_BACKTRACE
1620  depth = backtrace(syscall_cb_buf, MAX_DEPTH);
1621  /* Clean up the top stack frame so we get the real function
1622  * name for the most recently failing function. */
1623  clean_backtrace(syscall_cb_buf, depth, ctx);
1624 #endif /* defined(USE_BACKTRACE) */
1625 
1626  syscall_name = get_syscall_name(syscall);
1627 
1628  tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
1629  syscall_name,
1630  ")\n",
1631  NULL);
1632 
1633 #ifdef USE_BACKTRACE
1634  n_fds = tor_log_get_sigsafe_err_fds(&fds);
1635  for (i=0; i < n_fds; ++i)
1636  backtrace_symbols_fd(syscall_cb_buf, (int)depth, fds[i]);
1637 #endif
1638 
1639 #if defined(DEBUGGING_CLOSE)
1640  _exit(1); // exit ok: programming error has led to sandbox failure.
1641 #endif // DEBUGGING_CLOSE
1642 }
1643 
1644 /**
1645  * Function that adds a handler for SIGSYS, which is the signal thrown
1646  * when the application is issuing a syscall which is not allowed. The
1647  * main purpose of this function is to help with debugging by identifying
1648  * filtered syscalls.
1649  */
1650 static int
1651 install_sigsys_debugging(void)
1652 {
1653  struct sigaction act;
1654  sigset_t mask;
1655 
1656  memset(&act, 0, sizeof(act));
1657  sigemptyset(&mask);
1658  sigaddset(&mask, SIGSYS);
1659 
1660  act.sa_sigaction = &sigsys_debugging;
1661  act.sa_flags = SA_SIGINFO;
1662  if (sigaction(SIGSYS, &act, NULL) < 0) {
1663  log_err(LD_BUG,"(Sandbox) Failed to register SIGSYS signal handler");
1664  return -1;
1665  }
1666 
1667  if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
1668  log_err(LD_BUG,"(Sandbox) Failed call to sigprocmask()");
1669  return -2;
1670  }
1671 
1672  return 0;
1673 }
1674 
1675 /**
1676  * Function responsible of registering the sandbox_cfg_t list of parameter
1677  * syscall filters to the existing parameter list. This is used for incipient
1678  * multiple-sandbox support.
1679  */
1680 static int
1681 register_cfg(sandbox_cfg_t* cfg)
1682 {
1683  sandbox_cfg_t *elem = NULL;
1684 
1685  if (filter_dynamic == NULL) {
1686  filter_dynamic = cfg;
1687  return 0;
1688  }
1689 
1690  for (elem = filter_dynamic; elem->next != NULL; elem = elem->next)
1691  ;
1692 
1693  elem->next = cfg;
1694 
1695  return 0;
1696 }
1697 
1698 #endif /* defined(USE_LIBSECCOMP) */
1699 
1700 #ifdef USE_LIBSECCOMP
1701 /**
1702  * Initialises the syscall sandbox filter for any linux architecture, taking
1703  * into account various available features for different linux flavours.
1704  */
1705 static int
1706 initialise_libseccomp_sandbox(sandbox_cfg_t* cfg)
1707 {
1708  /* Prevent glibc from trying to open /dev/tty on fatal error */
1709  setenv("LIBC_FATAL_STDERR_", "1", 1);
1710 
1711  if (install_sigsys_debugging())
1712  return -1;
1713 
1714  if (install_syscall_filter(cfg))
1715  return -2;
1716 
1717  if (register_cfg(cfg))
1718  return -3;
1719 
1720  return 0;
1721 }
1722 
1723 int
1724 sandbox_is_active(void)
1725 {
1726  return sandbox_active != 0;
1727 }
1728 #endif /* defined(USE_LIBSECCOMP) */
1729 
1732 {
1733  return NULL;
1734 }
1735 
1736 int
1738 {
1739 #if defined(USE_LIBSECCOMP)
1740  return initialise_libseccomp_sandbox(cfg);
1741 
1742 #elif defined(__linux__)
1743  (void)cfg;
1744  log_warn(LD_GENERAL,
1745  "This version of Tor was built without support for sandboxing. To "
1746  "build with support for sandboxing on Linux, you must have "
1747  "libseccomp and its necessary header files (e.g. seccomp.h).");
1748  return 0;
1749 
1750 #else
1751  (void)cfg;
1752  log_warn(LD_GENERAL,
1753  "Currently, sandboxing is only implemented on Linux. The feature "
1754  "is disabled on your platform.");
1755  return 0;
1756 #endif /* defined(USE_LIBSECCOMP) || ... */
1757 }
1758 
1759 #ifndef USE_LIBSECCOMP
1760 int
1762 {
1763  (void)cfg; (void)file;
1764  return 0;
1765 }
1766 
1767 int
1769 {
1770  (void)cfg; (void)file;
1771  return 0;
1772 }
1773 
1774 int
1776 {
1777  (void)cfg; (void)file;
1778  return 0;
1779 }
1780 
1781 int
1782 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
1783 {
1784  (void)cfg; (void)file;
1785  return 0;
1786 }
1787 
1788 int
1789 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
1790 {
1791  (void)cfg; (void)file;
1792  return 0;
1793 }
1794 
1795 int
1796 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
1797 {
1798  (void)cfg; (void)file1; (void)file2;
1799  return 0;
1800 }
1801 
1802 int
1804 {
1805  return 0;
1806 }
1807 
1808 #endif /* !defined(USE_LIBSECCOMP) */
int tor_sscanf(const char *buf, const char *pattern,...)
Definition: scanf.c:309
struct sandbox_cfg_elem sandbox_cfg_t
Definition: sandbox.h:35
Header for backtrace.c.
void tor_log_err_sigsafe(const char *m,...)
Definition: torerr.c:70
Definitions for timing-related constants.
#define LD_GENERAL
Definition: log.h:62
int sandbox_is_active(void)
Definition: sandbox.c:1803
int sandbox_init(sandbox_cfg_t *cfg)
Definition: sandbox.c:1737
#define tor_free(p)
Definition: malloc.h:52
Integer definitions used throughout Tor.
Headers for util_malloc.c.
int sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
Definition: sandbox.c:1761
#define sandbox_intern_string(s)
Definition: sandbox.h:112
int format_dec_number_sigsafe(unsigned long x, char *buf, int buf_len)
Definition: torerr.c:307
Header file for sandbox.c.
#define SYS_SECCOMP
Definition: sandbox.h:24
Header for scanf.c.
#define MALLOC_MP_LIM
Definition: sandbox.c:29
int sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
Definition: sandbox.c:1775
#define ARRAY_LENGTH(x)
Headers for map.c.
Headers for torerr.c.
int tor_log_get_sigsafe_err_fds(const int **out)
Definition: torerr.c:103
Headers for log.c.
#define LD_BUG
Definition: log.h:86
int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
Definition: sandbox.c:1768
sandbox_cfg_t * sandbox_cfg_new(void)
Definition: sandbox.c:1731