tor  0.4.2.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 
12 #include "orconfig.h"
13 
14 #ifndef _LARGEFILE64_SOURCE
15 
19 #define _LARGEFILE64_SOURCE
20 #endif /* !defined(_LARGEFILE64_SOURCE) */
21 
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 
96 #if defined(__i386__)
97 
98 #define REG_SYSCALL REG_EAX
99 #define M_SYSCALL gregs[REG_SYSCALL]
100 
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 
121 static int sandbox_active = 0;
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 
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 
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 #ifdef SIGXFSZ
298  SIGXFSZ
299 #endif
300  };
301  (void) filter;
302 
303  for (i = 0; i < ARRAY_LENGTH(param); i++) {
304  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction),
305  SCMP_CMP(0, SCMP_CMP_EQ, param[i]));
306  if (rc)
307  break;
308  }
309 
310  return rc;
311 }
312 
317 static int
318 sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
319 {
320  (void) filter;
321 #ifdef __NR_time
322  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time),
323  SCMP_CMP(0, SCMP_CMP_EQ, 0));
324 #else
325  return 0;
326 #endif /* defined(__NR_time) */
327 }
328 
333 static int
334 sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
335 {
336  int rc = 0;
337  (void)filter;
338 
339 #ifdef __i386__
340  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall),
341  SCMP_CMP(0, SCMP_CMP_EQ, 18));
342  if (rc) {
343  return rc;
344  }
345 #endif /* defined(__i386__) */
346 
347  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4),
348  SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0));
349  if (rc) {
350  return rc;
351  }
352 
353  return 0;
354 }
355 
356 #ifdef __NR_mmap2
357 
361 static int
362 sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
363 {
364  int rc = 0;
365  (void)filter;
366 
367  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
368  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ),
369  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE));
370  if (rc) {
371  return rc;
372  }
373 
374  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
375  SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE),
376  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE));
377  if (rc) {
378  return rc;
379  }
380 
381  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
382  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
383  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS));
384  if (rc) {
385  return rc;
386  }
387 
388  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
389  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
390  SCMP_CMP(3, SCMP_CMP_EQ,MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK));
391  if (rc) {
392  return rc;
393  }
394 
395  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
396  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
397  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE));
398  if (rc) {
399  return rc;
400  }
401 
402  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
403  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
404  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS));
405  if (rc) {
406  return rc;
407  }
408 
409  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
410  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_EXEC),
411  SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_DENYWRITE));
412  if (rc) {
413  return rc;
414  }
415 
416  return 0;
417 }
418 #endif /* defined(__NR_mmap2) */
419 
420 #ifdef HAVE_GNU_LIBC_VERSION_H
421 #ifdef HAVE_GNU_GET_LIBC_VERSION
422 #define CHECK_LIBC_VERSION
423 #endif
424 #endif
425 
426 /* Return true if we think we're running with a libc that always uses
427  * openat on linux. */
428 static int
429 libc_uses_openat_for_everything(void)
430 {
431 #ifdef CHECK_LIBC_VERSION
432  const char *version = gnu_get_libc_version();
433  if (version == NULL)
434  return 0;
435 
436  int major = -1;
437  int minor = -1;
438 
439  tor_sscanf(version, "%d.%d", &major, &minor);
440  if (major >= 3)
441  return 1;
442  else if (major == 2 && minor >= 26)
443  return 1;
444  else
445  return 0;
446 #else /* !(defined(CHECK_LIBC_VERSION)) */
447  return 0;
448 #endif /* defined(CHECK_LIBC_VERSION) */
449 }
450 
453 static int
454 allow_file_open(scmp_filter_ctx ctx, int use_openat, const char *file)
455 {
456  if (use_openat) {
457  return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
458  SCMP_CMP(0, SCMP_CMP_EQ, (unsigned int)AT_FDCWD),
459  SCMP_CMP_STR(1, SCMP_CMP_EQ, file));
460  } else {
461  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),
462  SCMP_CMP_STR(0, SCMP_CMP_EQ, file));
463  }
464 }
465 
470 static int
471 sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
472 {
473  int rc;
474  sandbox_cfg_t *elem = NULL;
475 
476  int use_openat = libc_uses_openat_for_everything();
477 
478  // for each dynamic parameter filters
479  for (elem = filter; elem != NULL; elem = elem->next) {
480  smp_param_t *param = elem->param;
481 
482  if (param != NULL && param->prot == 1 && param->syscall
483  == SCMP_SYS(open)) {
484  rc = allow_file_open(ctx, use_openat, param->value);
485  if (rc != 0) {
486  log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
487  "libseccomp error %d", rc);
488  return rc;
489  }
490  }
491  }
492 
493  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open),
494  SCMP_CMP_MASKED(1, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW,
495  O_RDONLY));
496  if (rc != 0) {
497  log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp "
498  "error %d", rc);
499  return rc;
500  }
501 
502  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(openat),
503  SCMP_CMP_MASKED(2, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW,
504  O_RDONLY));
505  if (rc != 0) {
506  log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
507  "libseccomp error %d", rc);
508  return rc;
509  }
510 
511  return 0;
512 }
513 
514 static int
515 sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
516 {
517  int rc;
518  sandbox_cfg_t *elem = NULL;
519 
520  // for each dynamic parameter filters
521  for (elem = filter; elem != NULL; elem = elem->next) {
522  smp_param_t *param = elem->param;
523 
524  if (param != NULL && param->prot == 1 && param->syscall
525  == SCMP_SYS(chmod)) {
526  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod),
527  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
528  if (rc != 0) {
529  log_err(LD_BUG,"(Sandbox) failed to add chmod syscall, received "
530  "libseccomp error %d", rc);
531  return rc;
532  }
533  }
534  }
535 
536  return 0;
537 }
538 
539 static int
540 sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
541 {
542  int rc;
543  sandbox_cfg_t *elem = NULL;
544 
545  // for each dynamic parameter filters
546  for (elem = filter; elem != NULL; elem = elem->next) {
547  smp_param_t *param = elem->param;
548 
549  if (param != NULL && param->prot == 1 && param->syscall
550  == SCMP_SYS(chown)) {
551  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown),
552  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
553  if (rc != 0) {
554  log_err(LD_BUG,"(Sandbox) failed to add chown syscall, received "
555  "libseccomp error %d", rc);
556  return rc;
557  }
558  }
559  }
560 
561  return 0;
562 }
563 
564 static int
565 sb__sysctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
566 {
567  int rc;
568  (void) filter;
569  (void) ctx;
570 
571  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(_sysctl));
572  if (rc != 0) {
573  log_err(LD_BUG,"(Sandbox) failed to add _sysctl syscall, "
574  "received libseccomp error %d", rc);
575  return rc;
576  }
577 
578  return 0;
579 }
580 
585 static int
586 sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
587 {
588  int rc;
589  sandbox_cfg_t *elem = NULL;
590 
591  // for each dynamic parameter filters
592  for (elem = filter; elem != NULL; elem = elem->next) {
593  smp_param_t *param = elem->param;
594 
595  if (param != NULL && param->prot == 1 &&
596  param->syscall == SCMP_SYS(rename)) {
597 
598  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename),
599  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value),
600  SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2));
601  if (rc != 0) {
602  log_err(LD_BUG,"(Sandbox) failed to add rename syscall, received "
603  "libseccomp error %d", rc);
604  return rc;
605  }
606  }
607  }
608 
609  return 0;
610 }
611 
616 static int
617 sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
618 {
619  int rc;
620  sandbox_cfg_t *elem = NULL;
621 
622  // for each dynamic parameter filters
623  for (elem = filter; elem != NULL; elem = elem->next) {
624  smp_param_t *param = elem->param;
625 
626  if (param != NULL && param->prot == 1 && param->syscall
627  == SCMP_SYS(openat)) {
628  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
629  SCMP_CMP(0, SCMP_CMP_EQ, AT_FDCWD),
630  SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
631  SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
632  O_CLOEXEC));
633  if (rc != 0) {
634  log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
635  "libseccomp error %d", rc);
636  return rc;
637  }
638  }
639  }
640 
641  return 0;
642 }
643 
648 static int
649 sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
650 {
651  int rc = 0;
652  int i, j;
653  (void) filter;
654 
655 #ifdef __i386__
656  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket));
657  if (rc)
658  return rc;
659 #endif
660 
661  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
662  SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
663  SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM));
664  if (rc)
665  return rc;
666 
667  for (i = 0; i < 2; ++i) {
668  const int pf = i ? PF_INET : PF_INET6;
669  for (j=0; j < 3; ++j) {
670  const int type = (j == 0) ? SOCK_STREAM :
671  SOCK_DGRAM;
672  const int protocol = (j == 0) ? IPPROTO_TCP :
673  (j == 1) ? IPPROTO_IP :
674  IPPROTO_UDP;
675  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
676  SCMP_CMP(0, SCMP_CMP_EQ, pf),
677  SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, type),
678  SCMP_CMP(2, SCMP_CMP_EQ, protocol));
679  if (rc)
680  return rc;
681  }
682  }
683 
684  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
685  SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
686  SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM),
687  SCMP_CMP(2, SCMP_CMP_EQ, 0));
688  if (rc)
689  return rc;
690 
691  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
692  SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
693  SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_DGRAM),
694  SCMP_CMP(2, SCMP_CMP_EQ, 0));
695  if (rc)
696  return rc;
697 
698  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
699  SCMP_CMP(0, SCMP_CMP_EQ, PF_NETLINK),
700  SCMP_CMP_MASKED(1, SOCK_CLOEXEC, SOCK_RAW),
701  SCMP_CMP(2, SCMP_CMP_EQ, 0));
702  if (rc)
703  return rc;
704 
705  return 0;
706 }
707 
712 static int
713 sb_socketpair(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
714 {
715  int rc = 0;
716  (void) filter;
717 
718 #ifdef __i386__
719  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair));
720  if (rc)
721  return rc;
722 #endif
723 
724  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair),
725  SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
726  SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC));
727  if (rc)
728  return rc;
729 
730  return 0;
731 }
732 
733 #ifdef HAVE_KIST_SUPPORT
734 
735 #include <linux/sockios.h>
736 
737 static int
738 sb_ioctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
739 {
740  int rc;
741  (void) filter;
742 
743  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl),
744  SCMP_CMP(1, SCMP_CMP_EQ, SIOCOUTQNSD));
745  if (rc)
746  return rc;
747  return 0;
748 }
749 
750 #endif /* defined(HAVE_KIST_SUPPORT) */
751 
756 static int
757 sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
758 {
759  int rc = 0;
760  (void) filter;
761 
762 #ifdef __i386__
763  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt));
764  if (rc)
765  return rc;
766 #endif
767 
768  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
769  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
770  SCMP_CMP(2, SCMP_CMP_EQ, SO_REUSEADDR));
771  if (rc)
772  return rc;
773 
774  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
775  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
776  SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
777  if (rc)
778  return rc;
779 
780  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
781  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
782  SCMP_CMP(2, SCMP_CMP_EQ, SO_RCVBUF));
783  if (rc)
784  return rc;
785 
786 #ifdef HAVE_SYSTEMD
787  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
788  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
789  SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUFFORCE));
790  if (rc)
791  return rc;
792 #endif /* defined(HAVE_SYSTEMD) */
793 
794 #ifdef IP_TRANSPARENT
795  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
796  SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
797  SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT));
798  if (rc)
799  return rc;
800 #endif /* defined(IP_TRANSPARENT) */
801 
802 #ifdef IPV6_V6ONLY
803  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
804  SCMP_CMP(1, SCMP_CMP_EQ, IPPROTO_IPV6),
805  SCMP_CMP(2, SCMP_CMP_EQ, IPV6_V6ONLY));
806  if (rc)
807  return rc;
808 #endif /* defined(IPV6_V6ONLY) */
809 
810  return 0;
811 }
812 
817 static int
818 sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
819 {
820  int rc = 0;
821  (void) filter;
822 
823 #ifdef __i386__
824  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt));
825  if (rc)
826  return rc;
827 #endif
828 
829  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
830  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
831  SCMP_CMP(2, SCMP_CMP_EQ, SO_ERROR));
832  if (rc)
833  return rc;
834 
835  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
836  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
837  SCMP_CMP(2, SCMP_CMP_EQ, SO_ACCEPTCONN));
838  if (rc)
839  return rc;
840 
841 #ifdef HAVE_SYSTEMD
842  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
843  SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
844  SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
845  if (rc)
846  return rc;
847 #endif /* defined(HAVE_SYSTEMD) */
848 
849 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
850  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
851  SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
852  SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST));
853  if (rc)
854  return rc;
855 #endif /* defined(HAVE_LINUX_NETFILTER_IPV4_H) */
856 
857 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
858  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
859  SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6),
860  SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST));
861  if (rc)
862  return rc;
863 #endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */
864 
865 #ifdef HAVE_KIST_SUPPORT
866 #include <netinet/tcp.h>
867  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
868  SCMP_CMP(1, SCMP_CMP_EQ, SOL_TCP),
869  SCMP_CMP(2, SCMP_CMP_EQ, TCP_INFO));
870  if (rc)
871  return rc;
872 #endif /* defined(HAVE_KIST_SUPPORT) */
873 
874  return 0;
875 }
876 
877 #ifdef __NR_fcntl64
878 
882 static int
883 sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
884 {
885  int rc = 0;
886  (void) filter;
887 
888  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
889  SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL));
890  if (rc)
891  return rc;
892 
893  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
894  SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL),
895  SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK));
896  if (rc)
897  return rc;
898 
899  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
900  SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD));
901  if (rc)
902  return rc;
903 
904  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
905  SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD),
906  SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC));
907  if (rc)
908  return rc;
909 
910  return 0;
911 }
912 #endif /* defined(__NR_fcntl64) */
913 
920 static int
921 sb_epoll_ctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
922 {
923  int rc = 0;
924  (void) filter;
925 
926  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
927  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD));
928  if (rc)
929  return rc;
930 
931  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
932  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD));
933  if (rc)
934  return rc;
935 
936  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
937  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL));
938  if (rc)
939  return rc;
940 
941  return 0;
942 }
943 
951 static int
952 sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
953 {
954  int rc = 0;
955  (void) filter;
956 
957  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
958  SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE));
959  if (rc)
960  return rc;
961 
962  return 0;
963 }
964 
972 static int
973 sb_mprotect(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
974 {
975  int rc = 0;
976  (void) filter;
977 
978  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
979  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ));
980  if (rc)
981  return rc;
982 
983  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
984  SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE));
985  if (rc)
986  return rc;
987 
988  return 0;
989 }
990 
995 static int
996 sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
997 {
998  int rc = 0;
999  (void) filter;
1000 
1001  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
1002  SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK));
1003  if (rc)
1004  return rc;
1005 
1006  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
1007  SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK));
1008  if (rc)
1009  return rc;
1010 
1011  return 0;
1012 }
1013 
1020 static int
1021 sb_flock(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1022 {
1023  int rc = 0;
1024  (void) filter;
1025 
1026  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1027  SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB));
1028  if (rc)
1029  return rc;
1030 
1031  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1032  SCMP_CMP(1, SCMP_CMP_EQ, LOCK_UN));
1033  if (rc)
1034  return rc;
1035 
1036  return 0;
1037 }
1038 
1043 static int
1044 sb_futex(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1045 {
1046  int rc = 0;
1047  (void) filter;
1048 
1049  // can remove
1050  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1051  SCMP_CMP(1, SCMP_CMP_EQ,
1052  FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME));
1053  if (rc)
1054  return rc;
1055 
1056  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1057  SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
1058  if (rc)
1059  return rc;
1060 
1061  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1062  SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE));
1063  if (rc)
1064  return rc;
1065 
1066  return 0;
1067 }
1068 
1075 static int
1076 sb_mremap(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1077 {
1078  int rc = 0;
1079  (void) filter;
1080 
1081  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap),
1082  SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE));
1083  if (rc)
1084  return rc;
1085 
1086  return 0;
1087 }
1088 
1089 #ifdef __NR_stat64
1090 
1094 static int
1095 sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1096 {
1097  int rc = 0;
1098  sandbox_cfg_t *elem = NULL;
1099 
1100  // for each dynamic parameter filters
1101  for (elem = filter; elem != NULL; elem = elem->next) {
1102  smp_param_t *param = elem->param;
1103 
1104  if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
1105  || param->syscall == SCMP_SYS(stat64))) {
1106  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64),
1107  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
1108  if (rc != 0) {
1109  log_err(LD_BUG,"(Sandbox) failed to add stat64 syscall, received "
1110  "libseccomp error %d", rc);
1111  return rc;
1112  }
1113  }
1114  }
1115 
1116  return 0;
1117 }
1118 #endif /* defined(__NR_stat64) */
1119 
1120 static int
1121 sb_kill(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1122 {
1123  (void) filter;
1124 #ifdef __NR_kill
1125  /* Allow killing anything with signal 0 -- it isn't really a kill. */
1126  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(kill),
1127  SCMP_CMP(1, SCMP_CMP_EQ, 0));
1128 #else
1129  return 0;
1130 #endif /* defined(__NR_kill) */
1131 }
1132 
1137 static sandbox_filter_func_t filter_func[] = {
1138  sb_rt_sigaction,
1139  sb_rt_sigprocmask,
1140  sb_time,
1141  sb_accept4,
1142 #ifdef __NR_mmap2
1143  sb_mmap2,
1144 #endif
1145  sb_chown,
1146  sb_chmod,
1147  sb_open,
1148  sb_openat,
1149  sb__sysctl,
1150  sb_rename,
1151 #ifdef __NR_fcntl64
1152  sb_fcntl64,
1153 #endif
1154  sb_epoll_ctl,
1155  sb_prctl,
1156  sb_mprotect,
1157  sb_flock,
1158  sb_futex,
1159  sb_mremap,
1160 #ifdef __NR_stat64
1161  sb_stat64,
1162 #endif
1163 
1164  sb_socket,
1165  sb_setsockopt,
1166  sb_getsockopt,
1167  sb_socketpair,
1168 #ifdef HAVE_KIST_SUPPORT
1169  sb_ioctl,
1170 #endif
1171  sb_kill
1172 };
1173 
1174 const char *
1175 sandbox_intern_string(const char *str)
1176 {
1177  sandbox_cfg_t *elem;
1178 
1179  if (str == NULL)
1180  return NULL;
1181 
1182  for (elem = filter_dynamic; elem != NULL; elem = elem->next) {
1183  smp_param_t *param = elem->param;
1184 
1185  if (param->prot) {
1186  if (!strcmp(str, (char*)(param->value))) {
1187  return (char*)param->value;
1188  }
1189  if (param->value2 && !strcmp(str, (char*)param->value2)) {
1190  return (char*)param->value2;
1191  }
1192  }
1193  }
1194 
1195  if (sandbox_active)
1196  log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
1197  return str;
1198 }
1199 
1200 /* DOCDOC */
1201 static int
1202 prot_strings_helper(strmap_t *locations,
1203  char **pr_mem_next_p,
1204  size_t *pr_mem_left_p,
1205  char **value_p)
1206 {
1207  char *param_val;
1208  size_t param_size;
1209  void *location;
1210 
1211  if (*value_p == 0)
1212  return 0;
1213 
1214  param_val = (char*) *value_p;
1215  param_size = strlen(param_val) + 1;
1216  location = strmap_get(locations, param_val);
1217 
1218  if (location) {
1219  // We already interned this string.
1220  tor_free(param_val);
1221  *value_p = location;
1222  return 0;
1223  } else if (*pr_mem_left_p >= param_size) {
1224  // copy to protected
1225  location = *pr_mem_next_p;
1226  memcpy(location, param_val, param_size);
1227 
1228  // re-point el parameter to protected
1229  tor_free(param_val);
1230  *value_p = location;
1231 
1232  strmap_set(locations, location, location); /* good real estate advice */
1233 
1234  // move next available protected memory
1235  *pr_mem_next_p += param_size;
1236  *pr_mem_left_p -= param_size;
1237  return 0;
1238  } else {
1239  log_err(LD_BUG,"(Sandbox) insufficient protected memory!");
1240  return -1;
1241  }
1242 }
1243 
1250 static int
1251 prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
1252 {
1253  int ret = 0;
1254  size_t pr_mem_size = 0, pr_mem_left = 0;
1255  char *pr_mem_next = NULL, *pr_mem_base;
1256  sandbox_cfg_t *el = NULL;
1257  strmap_t *locations = NULL;
1258 
1259  // get total number of bytes required to mmap. (Overestimate.)
1260  for (el = cfg; el != NULL; el = el->next) {
1261  pr_mem_size += strlen((char*) el->param->value) + 1;
1262  if (el->param->value2)
1263  pr_mem_size += strlen((char*) el->param->value2) + 1;
1264  }
1265 
1266  // allocate protected memory with MALLOC_MP_LIM canary
1267  pr_mem_base = (char*) mmap(NULL, MALLOC_MP_LIM + pr_mem_size,
1268  PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
1269  if (pr_mem_base == MAP_FAILED) {
1270  log_err(LD_BUG,"(Sandbox) failed allocate protected memory! mmap: %s",
1271  strerror(errno));
1272  ret = -1;
1273  goto out;
1274  }
1275 
1276  pr_mem_next = pr_mem_base + MALLOC_MP_LIM;
1277  pr_mem_left = pr_mem_size;
1278 
1279  locations = strmap_new();
1280 
1281  // change el value pointer to protected
1282  for (el = cfg; el != NULL; el = el->next) {
1283  if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1284  &el->param->value) < 0) {
1285  ret = -2;
1286  goto out;
1287  }
1288  if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1289  &el->param->value2) < 0) {
1290  ret = -2;
1291  goto out;
1292  }
1293  el->param->prot = 1;
1294  }
1295 
1296  // protecting from writes
1297  if (mprotect(pr_mem_base, MALLOC_MP_LIM + pr_mem_size, PROT_READ)) {
1298  log_err(LD_BUG,"(Sandbox) failed to protect memory! mprotect: %s",
1299  strerror(errno));
1300  ret = -3;
1301  goto out;
1302  }
1303 
1304  /*
1305  * Setting sandbox restrictions so the string memory cannot be tampered with
1306  */
1307  // no mremap of the protected base address
1308  ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(mremap),
1309  SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1310  if (ret) {
1311  log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!");
1312  goto out;
1313  }
1314 
1315  // no munmap of the protected base address
1316  ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(munmap),
1317  SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1318  if (ret) {
1319  log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!");
1320  goto out;
1321  }
1322 
1323  /*
1324  * Allow mprotect with PROT_READ|PROT_WRITE because openssl uses it, but
1325  * never over the memory region used by the protected strings.
1326  *
1327  * PROT_READ|PROT_WRITE was originally fully allowed in sb_mprotect(), but
1328  * had to be removed due to limitation of libseccomp regarding intervals.
1329  *
1330  * There is a restriction on how much you can mprotect with R|W up to the
1331  * size of the canary.
1332  */
1333  ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1334  SCMP_CMP(0, SCMP_CMP_LT, (intptr_t) pr_mem_base),
1335  SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
1336  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1337  if (ret) {
1338  log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!");
1339  goto out;
1340  }
1341 
1342  ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1343  SCMP_CMP(0, SCMP_CMP_GT, (intptr_t) pr_mem_base + pr_mem_size +
1344  MALLOC_MP_LIM),
1345  SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
1346  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1347  if (ret) {
1348  log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!");
1349  goto out;
1350  }
1351 
1352  out:
1353  strmap_free(locations, NULL);
1354  return ret;
1355 }
1356 
1363 static sandbox_cfg_t*
1364 new_element2(int syscall, char *value, char *value2)
1365 {
1366  smp_param_t *param = NULL;
1367 
1368  sandbox_cfg_t *elem = tor_malloc_zero(sizeof(sandbox_cfg_t));
1369  param = elem->param = tor_malloc_zero(sizeof(smp_param_t));
1370 
1371  param->syscall = syscall;
1372  param->value = value;
1373  param->value2 = value2;
1374  param->prot = 0;
1375 
1376  return elem;
1377 }
1378 
1379 static sandbox_cfg_t*
1380 new_element(int syscall, char *value)
1381 {
1382  return new_element2(syscall, value, NULL);
1383 }
1384 
1385 #ifdef __NR_stat64
1386 #define SCMP_stat SCMP_SYS(stat64)
1387 #else
1388 #define SCMP_stat SCMP_SYS(stat)
1389 #endif
1390 
1391 int
1393 {
1394  sandbox_cfg_t *elem = NULL;
1395 
1396  elem = new_element(SCMP_stat, file);
1397 
1398  elem->next = *cfg;
1399  *cfg = elem;
1400 
1401  return 0;
1402 }
1403 
1404 int
1406 {
1407  sandbox_cfg_t *elem = NULL;
1408 
1409  elem = new_element(SCMP_SYS(open), file);
1410 
1411  elem->next = *cfg;
1412  *cfg = elem;
1413 
1414  return 0;
1415 }
1416 
1417 int
1418 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
1419 {
1420  sandbox_cfg_t *elem = NULL;
1421 
1422  elem = new_element(SCMP_SYS(chmod), file);
1423 
1424  elem->next = *cfg;
1425  *cfg = elem;
1426 
1427  return 0;
1428 }
1429 
1430 int
1431 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
1432 {
1433  sandbox_cfg_t *elem = NULL;
1434 
1435  elem = new_element(SCMP_SYS(chown), file);
1436 
1437  elem->next = *cfg;
1438  *cfg = elem;
1439 
1440  return 0;
1441 }
1442 
1443 int
1444 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
1445 {
1446  sandbox_cfg_t *elem = NULL;
1447 
1448  elem = new_element2(SCMP_SYS(rename), file1, file2);
1449 
1450  elem->next = *cfg;
1451  *cfg = elem;
1452 
1453  return 0;
1454 }
1455 
1456 int
1458 {
1459  sandbox_cfg_t *elem = NULL;
1460 
1461  elem = new_element(SCMP_SYS(openat), file);
1462 
1463  elem->next = *cfg;
1464  *cfg = elem;
1465 
1466  return 0;
1467 }
1468 
1473 static int
1474 add_param_filter(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
1475 {
1476  unsigned i;
1477  int rc = 0;
1478 
1479  // function pointer
1480  for (i = 0; i < ARRAY_LENGTH(filter_func); i++) {
1481  rc = filter_func[i](ctx, cfg);
1482  if (rc) {
1483  log_err(LD_BUG,"(Sandbox) failed to add syscall %d, received libseccomp "
1484  "error %d", i, rc);
1485  return rc;
1486  }
1487  }
1488 
1489  return 0;
1490 }
1491 
1496 static int
1497 add_noparam_filter(scmp_filter_ctx ctx)
1498 {
1499  unsigned i;
1500  int rc = 0;
1501 
1502  // add general filters
1503  for (i = 0; i < ARRAY_LENGTH(filter_nopar_gen); i++) {
1504  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i]);
1505  if (rc != 0) {
1506  log_err(LD_BUG,"(Sandbox) failed to add syscall index %d (NR=%d), "
1507  "received libseccomp error %d", i, filter_nopar_gen[i], rc);
1508  return rc;
1509  }
1510  }
1511 
1512  return 0;
1513 }
1514 
1520 static int
1521 install_syscall_filter(sandbox_cfg_t* cfg)
1522 {
1523  int rc = 0;
1524  scmp_filter_ctx ctx;
1525 
1526  ctx = seccomp_init(SCMP_ACT_TRAP);
1527  if (ctx == NULL) {
1528  log_err(LD_BUG,"(Sandbox) failed to initialise libseccomp context");
1529  rc = -1;
1530  goto end;
1531  }
1532 
1533  // protectign sandbox parameter strings
1534  if ((rc = prot_strings(ctx, cfg))) {
1535  goto end;
1536  }
1537 
1538  // add parameter filters
1539  if ((rc = add_param_filter(ctx, cfg))) {
1540  log_err(LD_BUG, "(Sandbox) failed to add param filters!");
1541  goto end;
1542  }
1543 
1544  // adding filters with no parameters
1545  if ((rc = add_noparam_filter(ctx))) {
1546  log_err(LD_BUG, "(Sandbox) failed to add param filters!");
1547  goto end;
1548  }
1549 
1550  // loading the seccomp2 filter
1551  if ((rc = seccomp_load(ctx))) {
1552  log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)! "
1553  "Are you sure that your kernel has seccomp2 support? The "
1554  "sandbox won't work without it.", rc,
1555  strerror(-rc));
1556  goto end;
1557  }
1558 
1559  // marking the sandbox as active
1560  sandbox_active = 1;
1561 
1562  end:
1563  seccomp_release(ctx);
1564  return (rc < 0 ? -rc : rc);
1565 }
1566 
1567 #include "lib/sandbox/linux_syscalls.inc"
1568 
1569 static const char *
1570 get_syscall_name(int syscall_num)
1571 {
1572  int i;
1573  for (i = 0; SYSCALLS_BY_NUMBER[i].syscall_name; ++i) {
1574  if (SYSCALLS_BY_NUMBER[i].syscall_num == syscall_num)
1575  return SYSCALLS_BY_NUMBER[i].syscall_name;
1576  }
1577 
1578  {
1579  static char syscall_name_buf[64];
1580  format_dec_number_sigsafe(syscall_num,
1581  syscall_name_buf, sizeof(syscall_name_buf));
1582  return syscall_name_buf;
1583  }
1584 }
1585 
1586 #ifdef USE_BACKTRACE
1587 #define MAX_DEPTH 256
1588 static void *syscall_cb_buf[MAX_DEPTH];
1589 #endif
1590 
1596 static void
1597 sigsys_debugging(int nr, siginfo_t *info, void *void_context)
1598 {
1599  ucontext_t *ctx = (ucontext_t *) (void_context);
1600  const char *syscall_name;
1601  int syscall;
1602 #ifdef USE_BACKTRACE
1603  size_t depth;
1604  int n_fds, i;
1605  const int *fds = NULL;
1606 #endif
1607 
1608  (void) nr;
1609 
1610  if (info->si_code != SYS_SECCOMP)
1611  return;
1612 
1613  if (!ctx)
1614  return;
1615 
1616  syscall = (int) ctx->uc_mcontext.M_SYSCALL;
1617 
1618 #ifdef USE_BACKTRACE
1619  depth = backtrace(syscall_cb_buf, MAX_DEPTH);
1620  /* Clean up the top stack frame so we get the real function
1621  * name for the most recently failing function. */
1622  clean_backtrace(syscall_cb_buf, depth, ctx);
1623 #endif /* defined(USE_BACKTRACE) */
1624 
1625  syscall_name = get_syscall_name(syscall);
1626 
1627  tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
1628  syscall_name,
1629  ")\n",
1630  NULL);
1631 
1632 #ifdef USE_BACKTRACE
1633  n_fds = tor_log_get_sigsafe_err_fds(&fds);
1634  for (i=0; i < n_fds; ++i)
1635  backtrace_symbols_fd(syscall_cb_buf, (int)depth, fds[i]);
1636 #endif
1637 
1638 #if defined(DEBUGGING_CLOSE)
1639  _exit(1); // exit ok: programming error has led to sandbox failure.
1640 #endif // DEBUGGING_CLOSE
1641 }
1642 
1649 static int
1650 install_sigsys_debugging(void)
1651 {
1652  struct sigaction act;
1653  sigset_t mask;
1654 
1655  memset(&act, 0, sizeof(act));
1656  sigemptyset(&mask);
1657  sigaddset(&mask, SIGSYS);
1658 
1659  act.sa_sigaction = &sigsys_debugging;
1660  act.sa_flags = SA_SIGINFO;
1661  if (sigaction(SIGSYS, &act, NULL) < 0) {
1662  log_err(LD_BUG,"(Sandbox) Failed to register SIGSYS signal handler");
1663  return -1;
1664  }
1665 
1666  if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
1667  log_err(LD_BUG,"(Sandbox) Failed call to sigprocmask()");
1668  return -2;
1669  }
1670 
1671  return 0;
1672 }
1673 
1679 static int
1680 register_cfg(sandbox_cfg_t* cfg)
1681 {
1682  sandbox_cfg_t *elem = NULL;
1683 
1684  if (filter_dynamic == NULL) {
1685  filter_dynamic = cfg;
1686  return 0;
1687  }
1688 
1689  for (elem = filter_dynamic; elem->next != NULL; elem = elem->next)
1690  ;
1691 
1692  elem->next = cfg;
1693 
1694  return 0;
1695 }
1696 
1697 #endif /* defined(USE_LIBSECCOMP) */
1698 
1699 #ifdef USE_LIBSECCOMP
1700 
1704 static int
1705 initialise_libseccomp_sandbox(sandbox_cfg_t* cfg)
1706 {
1707  /* Prevent glibc from trying to open /dev/tty on fatal error */
1708  setenv("LIBC_FATAL_STDERR_", "1", 1);
1709 
1710  if (install_sigsys_debugging())
1711  return -1;
1712 
1713  if (install_syscall_filter(cfg))
1714  return -2;
1715 
1716  if (register_cfg(cfg))
1717  return -3;
1718 
1719  return 0;
1720 }
1721 
1722 int
1723 sandbox_is_active(void)
1724 {
1725  return sandbox_active != 0;
1726 }
1727 #endif /* defined(USE_LIBSECCOMP) */
1728 
1731 {
1732  return NULL;
1733 }
1734 
1735 int
1737 {
1738 #if defined(USE_LIBSECCOMP)
1739  return initialise_libseccomp_sandbox(cfg);
1740 
1741 #elif defined(__linux__)
1742  (void)cfg;
1743  log_warn(LD_GENERAL,
1744  "This version of Tor was built without support for sandboxing. To "
1745  "build with support for sandboxing on Linux, you must have "
1746  "libseccomp and its necessary header files (e.g. seccomp.h).");
1747  return 0;
1748 
1749 #else
1750  (void)cfg;
1751  log_warn(LD_GENERAL,
1752  "Currently, sandboxing is only implemented on Linux. The feature "
1753  "is disabled on your platform.");
1754  return 0;
1755 #endif /* defined(USE_LIBSECCOMP) || ... */
1756 }
1757 
1758 #ifndef USE_LIBSECCOMP
1759 int
1761 {
1762  (void)cfg; (void)file;
1763  return 0;
1764 }
1765 
1766 int
1768 {
1769  (void)cfg; (void)file;
1770  return 0;
1771 }
1772 
1773 int
1775 {
1776  (void)cfg; (void)file;
1777  return 0;
1778 }
1779 
1780 int
1781 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
1782 {
1783  (void)cfg; (void)file;
1784  return 0;
1785 }
1786 
1787 int
1788 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
1789 {
1790  (void)cfg; (void)file;
1791  return 0;
1792 }
1793 
1794 int
1795 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
1796 {
1797  (void)cfg; (void)file1; (void)file2;
1798  return 0;
1799 }
1800 
1801 int
1803 {
1804  return 0;
1805 }
1806 
1807 #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:60
int sandbox_is_active(void)
Definition: sandbox.c:1802
int sandbox_init(sandbox_cfg_t *cfg)
Definition: sandbox.c:1736
#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:1760
#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:245
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:1774
#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:84
int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
Definition: sandbox.c:1767
sandbox_cfg_t * sandbox_cfg_new(void)
Definition: sandbox.c:1730