tor  0.4.0.1-alpha
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 #ifdef HAVE_SYSTEMD
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_SNDBUF));
839  if (rc)
840  return rc;
841 #endif /* defined(HAVE_SYSTEMD) */
842 
843 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
844  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
845  SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
846  SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST));
847  if (rc)
848  return rc;
849 #endif /* defined(HAVE_LINUX_NETFILTER_IPV4_H) */
850 
851 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
852  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
853  SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6),
854  SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST));
855  if (rc)
856  return rc;
857 #endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */
858 
859 #ifdef HAVE_KIST_SUPPORT
860 #include <netinet/tcp.h>
861  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
862  SCMP_CMP(1, SCMP_CMP_EQ, SOL_TCP),
863  SCMP_CMP(2, SCMP_CMP_EQ, TCP_INFO));
864  if (rc)
865  return rc;
866 #endif /* defined(HAVE_KIST_SUPPORT) */
867 
868  return 0;
869 }
870 
871 #ifdef __NR_fcntl64
872 
876 static int
877 sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
878 {
879  int rc = 0;
880  (void) filter;
881 
882  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
883  SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL));
884  if (rc)
885  return rc;
886 
887  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
888  SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL),
889  SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK));
890  if (rc)
891  return rc;
892 
893  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
894  SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD));
895  if (rc)
896  return rc;
897 
898  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
899  SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD),
900  SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC));
901  if (rc)
902  return rc;
903 
904  return 0;
905 }
906 #endif /* defined(__NR_fcntl64) */
907 
914 static int
915 sb_epoll_ctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
916 {
917  int rc = 0;
918  (void) filter;
919 
920  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
921  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD));
922  if (rc)
923  return rc;
924 
925  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
926  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD));
927  if (rc)
928  return rc;
929 
930  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
931  SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL));
932  if (rc)
933  return rc;
934 
935  return 0;
936 }
937 
945 static int
946 sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
947 {
948  int rc = 0;
949  (void) filter;
950 
951  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
952  SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE));
953  if (rc)
954  return rc;
955 
956  return 0;
957 }
958 
966 static int
967 sb_mprotect(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
968 {
969  int rc = 0;
970  (void) filter;
971 
972  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
973  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ));
974  if (rc)
975  return rc;
976 
977  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
978  SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE));
979  if (rc)
980  return rc;
981 
982  return 0;
983 }
984 
989 static int
990 sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
991 {
992  int rc = 0;
993  (void) filter;
994 
995  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
996  SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK));
997  if (rc)
998  return rc;
999 
1000  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
1001  SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK));
1002  if (rc)
1003  return rc;
1004 
1005  return 0;
1006 }
1007 
1014 static int
1015 sb_flock(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1016 {
1017  int rc = 0;
1018  (void) filter;
1019 
1020  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1021  SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB));
1022  if (rc)
1023  return rc;
1024 
1025  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
1026  SCMP_CMP(1, SCMP_CMP_EQ, LOCK_UN));
1027  if (rc)
1028  return rc;
1029 
1030  return 0;
1031 }
1032 
1037 static int
1038 sb_futex(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1039 {
1040  int rc = 0;
1041  (void) filter;
1042 
1043  // can remove
1044  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1045  SCMP_CMP(1, SCMP_CMP_EQ,
1046  FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME));
1047  if (rc)
1048  return rc;
1049 
1050  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1051  SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
1052  if (rc)
1053  return rc;
1054 
1055  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
1056  SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE));
1057  if (rc)
1058  return rc;
1059 
1060  return 0;
1061 }
1062 
1069 static int
1070 sb_mremap(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1071 {
1072  int rc = 0;
1073  (void) filter;
1074 
1075  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap),
1076  SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE));
1077  if (rc)
1078  return rc;
1079 
1080  return 0;
1081 }
1082 
1083 #ifdef __NR_stat64
1084 
1088 static int
1089 sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1090 {
1091  int rc = 0;
1092  sandbox_cfg_t *elem = NULL;
1093 
1094  // for each dynamic parameter filters
1095  for (elem = filter; elem != NULL; elem = elem->next) {
1096  smp_param_t *param = elem->param;
1097 
1098  if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
1099  || param->syscall == SCMP_SYS(stat64))) {
1100  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64),
1101  SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
1102  if (rc != 0) {
1103  log_err(LD_BUG,"(Sandbox) failed to add stat64 syscall, received "
1104  "libseccomp error %d", rc);
1105  return rc;
1106  }
1107  }
1108  }
1109 
1110  return 0;
1111 }
1112 #endif /* defined(__NR_stat64) */
1113 
1114 static int
1115 sb_kill(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
1116 {
1117  (void) filter;
1118 #ifdef __NR_kill
1119  /* Allow killing anything with signal 0 -- it isn't really a kill. */
1120  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(kill),
1121  SCMP_CMP(1, SCMP_CMP_EQ, 0));
1122 #else
1123  return 0;
1124 #endif /* defined(__NR_kill) */
1125 }
1126 
1131 static sandbox_filter_func_t filter_func[] = {
1132  sb_rt_sigaction,
1133  sb_rt_sigprocmask,
1134  sb_time,
1135  sb_accept4,
1136 #ifdef __NR_mmap2
1137  sb_mmap2,
1138 #endif
1139  sb_chown,
1140  sb_chmod,
1141  sb_open,
1142  sb_openat,
1143  sb__sysctl,
1144  sb_rename,
1145 #ifdef __NR_fcntl64
1146  sb_fcntl64,
1147 #endif
1148  sb_epoll_ctl,
1149  sb_prctl,
1150  sb_mprotect,
1151  sb_flock,
1152  sb_futex,
1153  sb_mremap,
1154 #ifdef __NR_stat64
1155  sb_stat64,
1156 #endif
1157 
1158  sb_socket,
1159  sb_setsockopt,
1160  sb_getsockopt,
1161  sb_socketpair,
1162 #ifdef HAVE_KIST_SUPPORT
1163  sb_ioctl,
1164 #endif
1165  sb_kill
1166 };
1167 
1168 const char *
1169 sandbox_intern_string(const char *str)
1170 {
1171  sandbox_cfg_t *elem;
1172 
1173  if (str == NULL)
1174  return NULL;
1175 
1176  for (elem = filter_dynamic; elem != NULL; elem = elem->next) {
1177  smp_param_t *param = elem->param;
1178 
1179  if (param->prot) {
1180  if (!strcmp(str, (char*)(param->value))) {
1181  return (char*)param->value;
1182  }
1183  if (param->value2 && !strcmp(str, (char*)param->value2)) {
1184  return (char*)param->value2;
1185  }
1186  }
1187  }
1188 
1189  if (sandbox_active)
1190  log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
1191  return str;
1192 }
1193 
1194 /* DOCDOC */
1195 static int
1196 prot_strings_helper(strmap_t *locations,
1197  char **pr_mem_next_p,
1198  size_t *pr_mem_left_p,
1199  char **value_p)
1200 {
1201  char *param_val;
1202  size_t param_size;
1203  void *location;
1204 
1205  if (*value_p == 0)
1206  return 0;
1207 
1208  param_val = (char*) *value_p;
1209  param_size = strlen(param_val) + 1;
1210  location = strmap_get(locations, param_val);
1211 
1212  if (location) {
1213  // We already interned this string.
1214  tor_free(param_val);
1215  *value_p = location;
1216  return 0;
1217  } else if (*pr_mem_left_p >= param_size) {
1218  // copy to protected
1219  location = *pr_mem_next_p;
1220  memcpy(location, param_val, param_size);
1221 
1222  // re-point el parameter to protected
1223  tor_free(param_val);
1224  *value_p = location;
1225 
1226  strmap_set(locations, location, location); /* good real estate advice */
1227 
1228  // move next available protected memory
1229  *pr_mem_next_p += param_size;
1230  *pr_mem_left_p -= param_size;
1231  return 0;
1232  } else {
1233  log_err(LD_BUG,"(Sandbox) insufficient protected memory!");
1234  return -1;
1235  }
1236 }
1237 
1244 static int
1245 prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
1246 {
1247  int ret = 0;
1248  size_t pr_mem_size = 0, pr_mem_left = 0;
1249  char *pr_mem_next = NULL, *pr_mem_base;
1250  sandbox_cfg_t *el = NULL;
1251  strmap_t *locations = NULL;
1252 
1253  // get total number of bytes required to mmap. (Overestimate.)
1254  for (el = cfg; el != NULL; el = el->next) {
1255  pr_mem_size += strlen((char*) el->param->value) + 1;
1256  if (el->param->value2)
1257  pr_mem_size += strlen((char*) el->param->value2) + 1;
1258  }
1259 
1260  // allocate protected memory with MALLOC_MP_LIM canary
1261  pr_mem_base = (char*) mmap(NULL, MALLOC_MP_LIM + pr_mem_size,
1262  PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
1263  if (pr_mem_base == MAP_FAILED) {
1264  log_err(LD_BUG,"(Sandbox) failed allocate protected memory! mmap: %s",
1265  strerror(errno));
1266  ret = -1;
1267  goto out;
1268  }
1269 
1270  pr_mem_next = pr_mem_base + MALLOC_MP_LIM;
1271  pr_mem_left = pr_mem_size;
1272 
1273  locations = strmap_new();
1274 
1275  // change el value pointer to protected
1276  for (el = cfg; el != NULL; el = el->next) {
1277  if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1278  &el->param->value) < 0) {
1279  ret = -2;
1280  goto out;
1281  }
1282  if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
1283  &el->param->value2) < 0) {
1284  ret = -2;
1285  goto out;
1286  }
1287  el->param->prot = 1;
1288  }
1289 
1290  // protecting from writes
1291  if (mprotect(pr_mem_base, MALLOC_MP_LIM + pr_mem_size, PROT_READ)) {
1292  log_err(LD_BUG,"(Sandbox) failed to protect memory! mprotect: %s",
1293  strerror(errno));
1294  ret = -3;
1295  goto out;
1296  }
1297 
1298  /*
1299  * Setting sandbox restrictions so the string memory cannot be tampered with
1300  */
1301  // no mremap of the protected base address
1302  ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(mremap),
1303  SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1304  if (ret) {
1305  log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!");
1306  goto out;
1307  }
1308 
1309  // no munmap of the protected base address
1310  ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(munmap),
1311  SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
1312  if (ret) {
1313  log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!");
1314  goto out;
1315  }
1316 
1317  /*
1318  * Allow mprotect with PROT_READ|PROT_WRITE because openssl uses it, but
1319  * never over the memory region used by the protected strings.
1320  *
1321  * PROT_READ|PROT_WRITE was originally fully allowed in sb_mprotect(), but
1322  * had to be removed due to limitation of libseccomp regarding intervals.
1323  *
1324  * There is a restriction on how much you can mprotect with R|W up to the
1325  * size of the canary.
1326  */
1327  ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1328  SCMP_CMP(0, SCMP_CMP_LT, (intptr_t) pr_mem_base),
1329  SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
1330  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1331  if (ret) {
1332  log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!");
1333  goto out;
1334  }
1335 
1336  ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
1337  SCMP_CMP(0, SCMP_CMP_GT, (intptr_t) pr_mem_base + pr_mem_size +
1338  MALLOC_MP_LIM),
1339  SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
1340  SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
1341  if (ret) {
1342  log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!");
1343  goto out;
1344  }
1345 
1346  out:
1347  strmap_free(locations, NULL);
1348  return ret;
1349 }
1350 
1357 static sandbox_cfg_t*
1358 new_element2(int syscall, char *value, char *value2)
1359 {
1360  smp_param_t *param = NULL;
1361 
1362  sandbox_cfg_t *elem = tor_malloc_zero(sizeof(sandbox_cfg_t));
1363  param = elem->param = tor_malloc_zero(sizeof(smp_param_t));
1364 
1365  param->syscall = syscall;
1366  param->value = value;
1367  param->value2 = value2;
1368  param->prot = 0;
1369 
1370  return elem;
1371 }
1372 
1373 static sandbox_cfg_t*
1374 new_element(int syscall, char *value)
1375 {
1376  return new_element2(syscall, value, NULL);
1377 }
1378 
1379 #ifdef __NR_stat64
1380 #define SCMP_stat SCMP_SYS(stat64)
1381 #else
1382 #define SCMP_stat SCMP_SYS(stat)
1383 #endif
1384 
1385 int
1387 {
1388  sandbox_cfg_t *elem = NULL;
1389 
1390  elem = new_element(SCMP_stat, file);
1391 
1392  elem->next = *cfg;
1393  *cfg = elem;
1394 
1395  return 0;
1396 }
1397 
1398 int
1400 {
1401  sandbox_cfg_t *elem = NULL;
1402 
1403  elem = new_element(SCMP_SYS(open), file);
1404 
1405  elem->next = *cfg;
1406  *cfg = elem;
1407 
1408  return 0;
1409 }
1410 
1411 int
1412 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
1413 {
1414  sandbox_cfg_t *elem = NULL;
1415 
1416  elem = new_element(SCMP_SYS(chmod), file);
1417 
1418  elem->next = *cfg;
1419  *cfg = elem;
1420 
1421  return 0;
1422 }
1423 
1424 int
1425 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
1426 {
1427  sandbox_cfg_t *elem = NULL;
1428 
1429  elem = new_element(SCMP_SYS(chown), file);
1430 
1431  elem->next = *cfg;
1432  *cfg = elem;
1433 
1434  return 0;
1435 }
1436 
1437 int
1438 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
1439 {
1440  sandbox_cfg_t *elem = NULL;
1441 
1442  elem = new_element2(SCMP_SYS(rename), file1, file2);
1443 
1444  elem->next = *cfg;
1445  *cfg = elem;
1446 
1447  return 0;
1448 }
1449 
1450 int
1452 {
1453  sandbox_cfg_t *elem = NULL;
1454 
1455  elem = new_element(SCMP_SYS(openat), file);
1456 
1457  elem->next = *cfg;
1458  *cfg = elem;
1459 
1460  return 0;
1461 }
1462 
1467 static int
1468 add_param_filter(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
1469 {
1470  unsigned i;
1471  int rc = 0;
1472 
1473  // function pointer
1474  for (i = 0; i < ARRAY_LENGTH(filter_func); i++) {
1475  rc = filter_func[i](ctx, cfg);
1476  if (rc) {
1477  log_err(LD_BUG,"(Sandbox) failed to add syscall %d, received libseccomp "
1478  "error %d", i, rc);
1479  return rc;
1480  }
1481  }
1482 
1483  return 0;
1484 }
1485 
1490 static int
1491 add_noparam_filter(scmp_filter_ctx ctx)
1492 {
1493  unsigned i;
1494  int rc = 0;
1495 
1496  // add general filters
1497  for (i = 0; i < ARRAY_LENGTH(filter_nopar_gen); i++) {
1498  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i]);
1499  if (rc != 0) {
1500  log_err(LD_BUG,"(Sandbox) failed to add syscall index %d (NR=%d), "
1501  "received libseccomp error %d", i, filter_nopar_gen[i], rc);
1502  return rc;
1503  }
1504  }
1505 
1506  return 0;
1507 }
1508 
1514 static int
1515 install_syscall_filter(sandbox_cfg_t* cfg)
1516 {
1517  int rc = 0;
1518  scmp_filter_ctx ctx;
1519 
1520  ctx = seccomp_init(SCMP_ACT_TRAP);
1521  if (ctx == NULL) {
1522  log_err(LD_BUG,"(Sandbox) failed to initialise libseccomp context");
1523  rc = -1;
1524  goto end;
1525  }
1526 
1527  // protectign sandbox parameter strings
1528  if ((rc = prot_strings(ctx, cfg))) {
1529  goto end;
1530  }
1531 
1532  // add parameter filters
1533  if ((rc = add_param_filter(ctx, cfg))) {
1534  log_err(LD_BUG, "(Sandbox) failed to add param filters!");
1535  goto end;
1536  }
1537 
1538  // adding filters with no parameters
1539  if ((rc = add_noparam_filter(ctx))) {
1540  log_err(LD_BUG, "(Sandbox) failed to add param filters!");
1541  goto end;
1542  }
1543 
1544  // loading the seccomp2 filter
1545  if ((rc = seccomp_load(ctx))) {
1546  log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)! "
1547  "Are you sure that your kernel has seccomp2 support? The "
1548  "sandbox won't work without it.", rc,
1549  strerror(-rc));
1550  goto end;
1551  }
1552 
1553  // marking the sandbox as active
1554  sandbox_active = 1;
1555 
1556  end:
1557  seccomp_release(ctx);
1558  return (rc < 0 ? -rc : rc);
1559 }
1560 
1561 #include "lib/sandbox/linux_syscalls.inc"
1562 
1563 static const char *
1564 get_syscall_name(int syscall_num)
1565 {
1566  int i;
1567  for (i = 0; SYSCALLS_BY_NUMBER[i].syscall_name; ++i) {
1568  if (SYSCALLS_BY_NUMBER[i].syscall_num == syscall_num)
1569  return SYSCALLS_BY_NUMBER[i].syscall_name;
1570  }
1571 
1572  {
1573  static char syscall_name_buf[64];
1574  format_dec_number_sigsafe(syscall_num,
1575  syscall_name_buf, sizeof(syscall_name_buf));
1576  return syscall_name_buf;
1577  }
1578 }
1579 
1580 #ifdef USE_BACKTRACE
1581 #define MAX_DEPTH 256
1582 static void *syscall_cb_buf[MAX_DEPTH];
1583 #endif
1584 
1590 static void
1591 sigsys_debugging(int nr, siginfo_t *info, void *void_context)
1592 {
1593  ucontext_t *ctx = (ucontext_t *) (void_context);
1594  const char *syscall_name;
1595  int syscall;
1596 #ifdef USE_BACKTRACE
1597  size_t depth;
1598  int n_fds, i;
1599  const int *fds = NULL;
1600 #endif
1601 
1602  (void) nr;
1603 
1604  if (info->si_code != SYS_SECCOMP)
1605  return;
1606 
1607  if (!ctx)
1608  return;
1609 
1610  syscall = (int) ctx->uc_mcontext.M_SYSCALL;
1611 
1612 #ifdef USE_BACKTRACE
1613  depth = backtrace(syscall_cb_buf, MAX_DEPTH);
1614  /* Clean up the top stack frame so we get the real function
1615  * name for the most recently failing function. */
1616  clean_backtrace(syscall_cb_buf, depth, ctx);
1617 #endif /* defined(USE_BACKTRACE) */
1618 
1619  syscall_name = get_syscall_name(syscall);
1620 
1621  tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
1622  syscall_name,
1623  ")\n",
1624  NULL);
1625 
1626 #ifdef USE_BACKTRACE
1627  n_fds = tor_log_get_sigsafe_err_fds(&fds);
1628  for (i=0; i < n_fds; ++i)
1629  backtrace_symbols_fd(syscall_cb_buf, (int)depth, fds[i]);
1630 #endif
1631 
1632 #if defined(DEBUGGING_CLOSE)
1633  _exit(1); // exit ok: programming error has led to sandbox failure.
1634 #endif // DEBUGGING_CLOSE
1635 }
1636 
1643 static int
1644 install_sigsys_debugging(void)
1645 {
1646  struct sigaction act;
1647  sigset_t mask;
1648 
1649  memset(&act, 0, sizeof(act));
1650  sigemptyset(&mask);
1651  sigaddset(&mask, SIGSYS);
1652 
1653  act.sa_sigaction = &sigsys_debugging;
1654  act.sa_flags = SA_SIGINFO;
1655  if (sigaction(SIGSYS, &act, NULL) < 0) {
1656  log_err(LD_BUG,"(Sandbox) Failed to register SIGSYS signal handler");
1657  return -1;
1658  }
1659 
1660  if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
1661  log_err(LD_BUG,"(Sandbox) Failed call to sigprocmask()");
1662  return -2;
1663  }
1664 
1665  return 0;
1666 }
1667 
1673 static int
1674 register_cfg(sandbox_cfg_t* cfg)
1675 {
1676  sandbox_cfg_t *elem = NULL;
1677 
1678  if (filter_dynamic == NULL) {
1679  filter_dynamic = cfg;
1680  return 0;
1681  }
1682 
1683  for (elem = filter_dynamic; elem->next != NULL; elem = elem->next)
1684  ;
1685 
1686  elem->next = cfg;
1687 
1688  return 0;
1689 }
1690 
1691 #endif /* defined(USE_LIBSECCOMP) */
1692 
1693 #ifdef USE_LIBSECCOMP
1694 
1698 static int
1699 initialise_libseccomp_sandbox(sandbox_cfg_t* cfg)
1700 {
1701  /* Prevent glibc from trying to open /dev/tty on fatal error */
1702  setenv("LIBC_FATAL_STDERR_", "1", 1);
1703 
1704  if (install_sigsys_debugging())
1705  return -1;
1706 
1707  if (install_syscall_filter(cfg))
1708  return -2;
1709 
1710  if (register_cfg(cfg))
1711  return -3;
1712 
1713  return 0;
1714 }
1715 
1716 int
1717 sandbox_is_active(void)
1718 {
1719  return sandbox_active != 0;
1720 }
1721 #endif /* defined(USE_LIBSECCOMP) */
1722 
1725 {
1726  return NULL;
1727 }
1728 
1729 int
1731 {
1732 #if defined(USE_LIBSECCOMP)
1733  return initialise_libseccomp_sandbox(cfg);
1734 
1735 #elif defined(__linux__)
1736  (void)cfg;
1737  log_warn(LD_GENERAL,
1738  "This version of Tor was built without support for sandboxing. To "
1739  "build with support for sandboxing on Linux, you must have "
1740  "libseccomp and its necessary header files (e.g. seccomp.h).");
1741  return 0;
1742 
1743 #else
1744  (void)cfg;
1745  log_warn(LD_GENERAL,
1746  "Currently, sandboxing is only implemented on Linux. The feature "
1747  "is disabled on your platform.");
1748  return 0;
1749 #endif /* defined(USE_LIBSECCOMP) || ... */
1750 }
1751 
1752 #ifndef USE_LIBSECCOMP
1753 int
1755 {
1756  (void)cfg; (void)file;
1757  return 0;
1758 }
1759 
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
1775 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
1776 {
1777  (void)cfg; (void)file;
1778  return 0;
1779 }
1780 
1781 int
1782 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
1783 {
1784  (void)cfg; (void)file;
1785  return 0;
1786 }
1787 
1788 int
1789 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
1790 {
1791  (void)cfg; (void)file1; (void)file2;
1792  return 0;
1793 }
1794 
1795 int
1797 {
1798  return 0;
1799 }
1800 
1801 #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:58
int sandbox_is_active(void)
Definition: sandbox.c:1796
int sandbox_init(sandbox_cfg_t *cfg)
Definition: sandbox.c:1730
#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:1754
#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:1768
#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:82
int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
Definition: sandbox.c:1761
sandbox_cfg_t * sandbox_cfg_new(void)
Definition: sandbox.c:1724