tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

sandbox.c (60974B)


      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-2021, 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 has 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 #ifdef ENABLE_FRAGILE_HARDENING
     62 #include <sys/ptrace.h>
     63 #endif
     64 
     65 #include <stdarg.h>
     66 #include <seccomp.h>
     67 #include <signal.h>
     68 #include <unistd.h>
     69 #include <fcntl.h>
     70 #include <time.h>
     71 #include <poll.h>
     72 
     73 #ifdef HAVE_GNU_LIBC_VERSION_H
     74 #include <gnu/libc-version.h>
     75 #endif
     76 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
     77 #include <linux/netfilter_ipv4.h>
     78 #endif
     79 #ifdef HAVE_LINUX_IF_H
     80 #include <linux/if.h>
     81 #endif
     82 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
     83 #include <linux/netfilter_ipv6/ip6_tables.h>
     84 #endif
     85 
     86 #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
     87  defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
     88 #define USE_BACKTRACE
     89 #define BACKTRACE_PRIVATE
     90 #include "lib/err/backtrace.h"
     91 #endif /* defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && ... */
     92 
     93 #ifdef USE_BACKTRACE
     94 #include <execinfo.h>
     95 #endif
     96 
     97 /**
     98 * Linux 32 bit definitions
     99 */
    100 #if defined(__i386__)
    101 
    102 #define REG_SYSCALL REG_EAX
    103 #define M_SYSCALL gregs[REG_SYSCALL]
    104 
    105 /**
    106 * Linux 64 bit definitions
    107 */
    108 #elif defined(__x86_64__)
    109 
    110 #define REG_SYSCALL REG_RAX
    111 #define M_SYSCALL gregs[REG_SYSCALL]
    112 
    113 #elif defined(__arm__)
    114 
    115 #define M_SYSCALL arm_r7
    116 
    117 #elif defined(__aarch64__) && defined(__LP64__)
    118 
    119 #define REG_SYSCALL 8
    120 #define M_SYSCALL regs[REG_SYSCALL]
    121 
    122 #endif /* defined(__i386__) || ... */
    123 
    124 #ifdef M_SYSCALL
    125 #define SYSCALL_NAME_DEBUGGING
    126 #endif
    127 
    128 /**
    129 * On newer architectures Linux provides a standardized, generic set of system
    130 * calls (defined in Linux's include/uapi/asm-generic/unistd.h), which omits a
    131 * number of legacy calls used by glibc on other platforms.
    132 */
    133 #if defined(__aarch64__) || defined(__riscv)
    134 #define ARCH_USES_GENERIC_SYSCALLS
    135 #endif
    136 
    137 /**Determines if at least one sandbox is active.*/
    138 static int sandbox_active = 0;
    139 /** Holds the parameter list configuration for the sandbox.*/
    140 static sandbox_cfg_t *filter_dynamic = NULL;
    141 
    142 #undef SCMP_CMP
    143 #define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0})
    144 #define SCMP_CMP_STR(a,b,c) \
    145  ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0})
    146 #define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)})
    147 /* We use a wrapper here because these masked comparisons seem to be pretty
    148 * verbose. Also, it's important to cast to scmp_datum_t before negating the
    149 * mask, since otherwise the negation might get applied to a 32 bit value, and
    150 * the high bits of the value might get masked out improperly. */
    151 #define SCMP_CMP_MASKED(a,b,c) \
    152  SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c))
    153 /* Negative constants aren't consistently sign extended or zero extended.
    154 * Different compilers, libc, and architectures behave differently. For cases
    155 * where the kernel ABI uses a 32 bit integer, this macro can be used to
    156 * mask-compare only the lower 32 bits of the value. */
    157 #define SCMP_CMP_LOWER32_EQ(a,b) \
    158  SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, 0xFFFFFFFF, (unsigned int)(b))
    159 
    160 /** Variable used for storing all syscall numbers that will be allowed with the
    161 * stage 1 general Tor sandbox.
    162 */
    163 static int filter_nopar_gen[] = {
    164    SCMP_SYS(access),
    165    SCMP_SYS(brk),
    166 #ifdef __NR_clock_gettime64
    167    SCMP_SYS(clock_gettime64),
    168 #else
    169    SCMP_SYS(clock_gettime),
    170 #endif
    171    SCMP_SYS(close),
    172    SCMP_SYS(clone),
    173    SCMP_SYS(dup),
    174 #ifdef __NR_clone3
    175    SCMP_SYS(clone3),
    176 #endif
    177    SCMP_SYS(epoll_create),
    178    SCMP_SYS(epoll_wait),
    179 #ifdef __NR_epoll_pwait
    180    SCMP_SYS(epoll_pwait),
    181 #endif
    182 #ifdef HAVE_EVENTFD
    183    SCMP_SYS(eventfd2),
    184 #endif
    185 #ifdef HAVE_PIPE2
    186    SCMP_SYS(pipe2),
    187 #endif
    188 #ifdef HAVE_PIPE
    189    SCMP_SYS(pipe),
    190 #endif
    191 #ifdef __NR_fchmod
    192    SCMP_SYS(fchmod),
    193 #endif
    194    SCMP_SYS(fcntl),
    195    SCMP_SYS(fstat),
    196 #ifdef __NR_fstat64
    197    SCMP_SYS(fstat64),
    198 #endif
    199    SCMP_SYS(fsync),
    200    SCMP_SYS(futex),
    201    SCMP_SYS(getdents),
    202    SCMP_SYS(getdents64),
    203    SCMP_SYS(getegid),
    204 #ifdef __NR_getegid32
    205    SCMP_SYS(getegid32),
    206 #endif
    207    SCMP_SYS(geteuid),
    208 #ifdef __NR_geteuid32
    209    SCMP_SYS(geteuid32),
    210 #endif
    211    SCMP_SYS(getgid),
    212 #ifdef __NR_getgid32
    213    SCMP_SYS(getgid32),
    214 #endif
    215    SCMP_SYS(getpid),
    216 #ifdef ENABLE_FRAGILE_HARDENING
    217    SCMP_SYS(getppid),
    218 #endif
    219 #ifdef __NR_getrlimit
    220    SCMP_SYS(getrlimit),
    221 #endif
    222    SCMP_SYS(gettimeofday),
    223    SCMP_SYS(gettid),
    224    SCMP_SYS(getuid),
    225 #ifdef __NR_getuid32
    226    SCMP_SYS(getuid32),
    227 #endif
    228    SCMP_SYS(lseek),
    229 #ifdef __NR__llseek
    230    SCMP_SYS(_llseek),
    231 #endif
    232    // glob uses this..
    233    SCMP_SYS(lstat),
    234 #ifdef __NR_membarrier
    235    /* Inter-processor synchronization, needed for tracing support */
    236    SCMP_SYS(membarrier),
    237 #endif
    238    SCMP_SYS(mkdir),
    239    SCMP_SYS(mlockall),
    240 #ifdef __NR_mmap
    241    /* XXXX restrict this in the same ways as mmap2 */
    242    SCMP_SYS(mmap),
    243 #endif
    244    SCMP_SYS(munmap),
    245 #ifdef __NR_nanosleep
    246    SCMP_SYS(nanosleep),
    247 #endif
    248 #ifdef __NR_prlimit
    249    SCMP_SYS(prlimit),
    250 #endif
    251 #ifdef __NR_prlimit64
    252    SCMP_SYS(prlimit64),
    253 #endif
    254    SCMP_SYS(read),
    255    SCMP_SYS(rt_sigreturn),
    256 #ifdef __NR_rseq
    257    SCMP_SYS(rseq),
    258 #endif
    259    SCMP_SYS(sched_getaffinity),
    260 #ifdef __NR_sched_yield
    261    SCMP_SYS(sched_yield),
    262 #endif
    263    SCMP_SYS(sendmsg),
    264    SCMP_SYS(set_robust_list),
    265 #ifdef __NR_setrlimit
    266    SCMP_SYS(setrlimit),
    267 #endif
    268    SCMP_SYS(shutdown),
    269 #ifdef __NR_sigaltstack
    270    SCMP_SYS(sigaltstack),
    271 #endif
    272 #ifdef __NR_sigreturn
    273    SCMP_SYS(sigreturn),
    274 #endif
    275 #if defined(__NR_stat)
    276    SCMP_SYS(stat),
    277 #elif defined(__i386__) && defined(__NR_statx)
    278    SCMP_SYS(statx),
    279 #endif
    280    SCMP_SYS(uname),
    281    SCMP_SYS(wait4),
    282    SCMP_SYS(write),
    283    SCMP_SYS(writev),
    284    SCMP_SYS(exit_group),
    285    SCMP_SYS(exit),
    286 
    287    SCMP_SYS(madvise),
    288 #ifdef __NR_stat64
    289    // getaddrinfo uses this..
    290    SCMP_SYS(stat64),
    291 #endif
    292 #ifdef __NR_lstat64
    293    // glob uses this on i386 with glibc 2.36+
    294    SCMP_SYS(lstat64),
    295 #endif
    296 
    297 #ifdef __NR_getrandom
    298    SCMP_SYS(getrandom),
    299 #endif
    300 
    301 #ifdef __NR_sysinfo
    302    // qsort uses this..
    303    SCMP_SYS(sysinfo),
    304 #endif
    305    /*
    306     * These socket syscalls are not required on x86_64 and not supported with
    307     * some libseccomp versions (eg: 1.0.1)
    308     */
    309 #if defined(__i386)
    310    SCMP_SYS(recv),
    311    SCMP_SYS(send),
    312 #endif
    313 
    314    // socket syscalls
    315    SCMP_SYS(bind),
    316    SCMP_SYS(listen),
    317    SCMP_SYS(connect),
    318    SCMP_SYS(getsockname),
    319 #ifdef ENABLE_NSS
    320 #ifdef __NR_getpeername
    321    SCMP_SYS(getpeername),
    322 #endif
    323 #endif
    324    SCMP_SYS(recvmsg),
    325    SCMP_SYS(recvfrom),
    326    SCMP_SYS(sendto),
    327    SCMP_SYS(unlink),
    328 #ifdef __NR_unlinkat
    329    SCMP_SYS(unlinkat),
    330 #endif
    331    SCMP_SYS(poll)
    332 };
    333 
    334 /* opendir is not a syscall but it will use either open or openat. We do not
    335 * want the decision to allow open/openat to be the callers responsibility, so
    336 * we create a phony syscall number for opendir and sb_opendir will choose the
    337 * correct syscall. */
    338 #define PHONY_OPENDIR_SYSCALL -2
    339 
    340 /* These macros help avoid the error where the number of filters we add on a
    341 * single rule don't match the arg_cnt param. */
    342 #define seccomp_rule_add_0(ctx,act,call) \
    343  seccomp_rule_add((ctx),(act),(call),0)
    344 #define seccomp_rule_add_1(ctx,act,call,f1) \
    345  seccomp_rule_add((ctx),(act),(call),1,(f1))
    346 #define seccomp_rule_add_2(ctx,act,call,f1,f2)  \
    347  seccomp_rule_add((ctx),(act),(call),2,(f1),(f2))
    348 #define seccomp_rule_add_3(ctx,act,call,f1,f2,f3)       \
    349  seccomp_rule_add((ctx),(act),(call),3,(f1),(f2),(f3))
    350 #define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4)      \
    351  seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4))
    352 #define seccomp_rule_add_5(ctx,act,call,f1,f2,f3,f4,f5)       \
    353  seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4),(f5))
    354 
    355 static const char *sandbox_get_interned_string(const char *str);
    356 
    357 /**
    358 * Function responsible for setting up the rt_sigaction syscall for
    359 * the seccomp filter sandbox.
    360 */
    361 static int
    362 sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    363 {
    364  unsigned i;
    365  int rc;
    366  int param[] = { SIGINT, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, SIGHUP, SIGCHLD,
    367                  SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, SIGIO,
    368 #ifdef SIGXFSZ
    369      SIGXFSZ
    370 #endif
    371      };
    372  (void) filter;
    373 
    374  for (i = 0; i < ARRAY_LENGTH(param); i++) {
    375    rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction),
    376        SCMP_CMP(0, SCMP_CMP_EQ, param[i]));
    377    if (rc)
    378      break;
    379  }
    380 
    381  return rc;
    382 }
    383 
    384 #ifdef __NR_time
    385 /**
    386 * Function responsible for setting up the time syscall for
    387 * the seccomp filter sandbox.
    388 */
    389 static int
    390 sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    391 {
    392  (void) filter;
    393 
    394  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time),
    395       SCMP_CMP(0, SCMP_CMP_EQ, 0));
    396 }
    397 #endif /* defined(__NR_time) */
    398 
    399 /**
    400 * Function responsible for setting up the accept4 syscall for
    401 * the seccomp filter sandbox.
    402 */
    403 static int
    404 sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    405 {
    406  int rc = 0;
    407  (void)filter;
    408 
    409 #ifdef __i386__
    410  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall),
    411      SCMP_CMP(0, SCMP_CMP_EQ, 18));
    412  if (rc) {
    413    return rc;
    414  }
    415 #endif /* defined(__i386__) */
    416 
    417  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4),
    418                   SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0));
    419  if (rc) {
    420    return rc;
    421  }
    422 
    423  return 0;
    424 }
    425 
    426 #ifdef __NR_mmap2
    427 /**
    428 * Function responsible for setting up the mmap2 syscall for
    429 * the seccomp filter sandbox.
    430 */
    431 static int
    432 sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    433 {
    434  int rc = 0;
    435  (void)filter;
    436 
    437  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
    438       SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ),
    439       SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE));
    440  if (rc) {
    441    return rc;
    442  }
    443 
    444  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
    445       SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE),
    446       SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE));
    447  if (rc) {
    448    return rc;
    449  }
    450 
    451  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
    452       SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
    453       SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS));
    454  if (rc) {
    455    return rc;
    456  }
    457 
    458  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
    459       SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
    460       SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK));
    461  if (rc) {
    462    return rc;
    463  }
    464 
    465  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
    466       SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE),
    467       SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK));
    468  if (rc) {
    469    return rc;
    470  }
    471 
    472  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
    473      SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
    474      SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE));
    475  if (rc) {
    476    return rc;
    477  }
    478 
    479  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
    480      SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
    481      SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS));
    482  if (rc) {
    483    return rc;
    484  }
    485 
    486  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2),
    487      SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_EXEC),
    488      SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_DENYWRITE));
    489  if (rc) {
    490    return rc;
    491  }
    492 
    493  return 0;
    494 }
    495 #endif /* defined(__NR_mmap2) */
    496 
    497 #ifdef HAVE_GNU_LIBC_VERSION_H
    498 #ifdef HAVE_GNU_GET_LIBC_VERSION
    499 #define CHECK_LIBC_VERSION
    500 #endif
    501 #endif
    502 
    503 /* Return true the libc version is greater or equal than
    504 * <b>major</b>.<b>minor</b>. Returns false otherwise. */
    505 static int
    506 is_libc_at_least(int major, int minor)
    507 {
    508 #ifdef CHECK_LIBC_VERSION
    509  const char *version = gnu_get_libc_version();
    510  if (version == NULL)
    511    return 0;
    512 
    513  int libc_major = -1;
    514  int libc_minor = -1;
    515 
    516  tor_sscanf(version, "%d.%d", &libc_major, &libc_minor);
    517  if (libc_major > major)
    518    return 1;
    519  else if (libc_major == major && libc_minor >= minor)
    520    return 1;
    521  else
    522    return 0;
    523 #else /* !defined(CHECK_LIBC_VERSION) */
    524  (void)major;
    525  (void)minor;
    526  return 0;
    527 #endif /* defined(CHECK_LIBC_VERSION) */
    528 }
    529 
    530 /* Return true if we think we're running with a libc that uses openat for the
    531 * open function on linux. */
    532 static int
    533 libc_uses_openat_for_open(void)
    534 {
    535 #ifdef __NR_open
    536  return is_libc_at_least(2, 26);
    537 #else
    538  return 1;
    539 #endif /* defined(__NR_open) */
    540 }
    541 
    542 /* Calls to opendir() cannot be filtered by the sandbox when built with fragile
    543 * hardening for an architecture that uses Linux's generic syscall interface,
    544 * so prevent a compiler warning by omitting this function along with
    545 * sb_opendir(). */
    546 #if !(defined(ENABLE_FRAGILE_HARDENING) && defined(ARCH_USES_GENERIC_SYSCALLS))
    547 /* Return true if we think we're running with a libc that uses openat for the
    548 * opendir function on linux. */
    549 static int
    550 libc_uses_openat_for_opendir(void)
    551 {
    552 #ifdef __NR_open
    553  // libc 2.27 and above or between 2.15 (inclusive) and 2.22 (exclusive)
    554  return is_libc_at_least(2, 27) ||
    555         (is_libc_at_least(2, 15) && !is_libc_at_least(2, 22));
    556 #else
    557  return 1;
    558 #endif /* defined(__NR_open) */
    559 }
    560 #endif /* !(defined(ENABLE_FRAGILE_HARDENING) &&
    561            defined(ARCH_USES_GENERIC_SYSCALLS)) */
    562 
    563 /** Allow a single file to be opened.  If <b>use_openat</b> is true,
    564 * we're using a libc that remaps all the opens into openats. */
    565 static int
    566 allow_file_open(scmp_filter_ctx ctx, int use_openat, const char *file)
    567 {
    568  if (use_openat) {
    569    return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
    570                              SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
    571                              SCMP_CMP_STR(1, SCMP_CMP_EQ, file));
    572  } else {
    573    return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),
    574                              SCMP_CMP_STR(0, SCMP_CMP_EQ, file));
    575  }
    576 }
    577 
    578 /**
    579 * Function responsible for setting up the open syscall for
    580 * the seccomp filter sandbox.
    581 */
    582 static int
    583 sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    584 {
    585  int rc;
    586  sandbox_cfg_t *elem = NULL;
    587 
    588  int use_openat = libc_uses_openat_for_open();
    589 
    590 #ifdef ENABLE_FRAGILE_HARDENING
    591  /* AddressSanitizer uses either the "open" or the "openat" syscall (depending
    592   * on the architecture) to access information about the running process via
    593   * the filesystem, so the appropriate call must be allowed without
    594   * restriction or the sanitizer will be unable to execute normally when the
    595   * process terminates. */
    596 #ifdef ARCH_USES_GENERIC_SYSCALLS
    597  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
    598      SCMP_CMP_LOWER32_EQ(0, AT_FDCWD));
    599  if (rc != 0) {
    600    log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
    601        "libseccomp error %d", rc);
    602    return rc;
    603  }
    604 
    605  /* The "open" syscall is not defined on this architecture, so any other
    606   * requests to open files will necessarily use "openat" as well and there is
    607   * no need to consider any additional rules. */
    608  return 0;
    609 #else
    610  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open));
    611  if (rc != 0) {
    612    log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
    613        "libseccomp error %d", rc);
    614    return rc;
    615  }
    616 
    617  /* If glibc also uses only the "open" syscall to open files on this system
    618   * there is no need to consider any additional rules. */
    619  if (!use_openat)
    620    return 0;
    621 #endif /* defined(ARCH_USES_GENERIC_SYSCALLS) */
    622 #endif /* defined(ENABLE_FRAGILE_HARDENING) */
    623 
    624  // for each dynamic parameter filters
    625  for (elem = filter; elem != NULL; elem = elem->next) {
    626    smp_param_t *param = elem->param;
    627 
    628    if (param != NULL && param->prot == 1 && param->syscall
    629        == SCMP_SYS(open)) {
    630      rc = allow_file_open(ctx, use_openat, param->value);
    631      if (rc != 0) {
    632        log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
    633            "libseccomp error %d", rc);
    634        return rc;
    635      }
    636    }
    637  }
    638 
    639  return 0;
    640 }
    641 
    642 #ifdef ARCH_USES_GENERIC_SYSCALLS
    643 static int
    644 sb_fchmodat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    645 {
    646  int rc;
    647  sandbox_cfg_t *elem = NULL;
    648 
    649  // for each dynamic parameter filters
    650  for (elem = filter; elem != NULL; elem = elem->next) {
    651    smp_param_t *param = elem->param;
    652 
    653    if (param != NULL && param->prot == 1 && param->syscall
    654        == SCMP_SYS(fchmodat)) {
    655      rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchmodat),
    656          SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
    657          SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value));
    658      if (rc != 0) {
    659        log_err(LD_BUG,"(Sandbox) failed to add fchmodat syscall, received "
    660            "libseccomp error %d", rc);
    661        return rc;
    662      }
    663    }
    664  }
    665 
    666  return 0;
    667 }
    668 #else
    669 static int
    670 sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    671 {
    672  int rc;
    673  sandbox_cfg_t *elem = NULL;
    674 
    675  // for each dynamic parameter filters
    676  for (elem = filter; elem != NULL; elem = elem->next) {
    677    smp_param_t *param = elem->param;
    678 
    679    if (param != NULL && param->prot == 1 && param->syscall
    680        == SCMP_SYS(chmod)) {
    681      rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod),
    682            SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
    683      if (rc != 0) {
    684        log_err(LD_BUG,"(Sandbox) failed to add chmod syscall, received "
    685            "libseccomp error %d", rc);
    686        return rc;
    687      }
    688    }
    689  }
    690 
    691  return 0;
    692 }
    693 #endif /* defined(ARCH_USES_GENERIC_SYSCALLS) */
    694 
    695 #if defined(ARCH_USES_GENERIC_SYSCALLS)
    696 static int
    697 sb_fchownat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    698 {
    699  int rc;
    700  sandbox_cfg_t *elem = NULL;
    701 
    702  // for each dynamic parameter filters
    703  for (elem = filter; elem != NULL; elem = elem->next) {
    704    smp_param_t *param = elem->param;
    705 
    706    if (param != NULL && param->prot == 1 && param->syscall
    707        == SCMP_SYS(fchownat)) {
    708      rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchownat),
    709          SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
    710          SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value));
    711      if (rc != 0) {
    712        log_err(LD_BUG,"(Sandbox) failed to add fchownat syscall, received "
    713            "libseccomp error %d", rc);
    714        return rc;
    715      }
    716    }
    717  }
    718 
    719  return 0;
    720 }
    721 #elif defined(__i386__)
    722 static int
    723 sb_chown32(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    724 {
    725  int rc;
    726  sandbox_cfg_t *elem = NULL;
    727 
    728  // for each dynamic parameter filters
    729  for (elem = filter; elem != NULL; elem = elem->next) {
    730    smp_param_t *param = elem->param;
    731 
    732    if (param != NULL && param->prot == 1 && param->syscall
    733        == SCMP_SYS(chown32)) {
    734      rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown32),
    735            SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
    736      if (rc != 0) {
    737        log_err(LD_BUG,"(Sandbox) failed to add chown32 syscall, received "
    738            "libseccomp error %d", rc);
    739        return rc;
    740      }
    741    }
    742  }
    743 
    744  return 0;
    745 }
    746 #else
    747 static int
    748 sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    749 {
    750  int rc;
    751  sandbox_cfg_t *elem = NULL;
    752 
    753  // for each dynamic parameter filters
    754  for (elem = filter; elem != NULL; elem = elem->next) {
    755    smp_param_t *param = elem->param;
    756 
    757    if (param != NULL && param->prot == 1 && param->syscall
    758        == SCMP_SYS(chown)) {
    759      rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown),
    760            SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
    761      if (rc != 0) {
    762        log_err(LD_BUG,"(Sandbox) failed to add chown syscall, received "
    763            "libseccomp error %d", rc);
    764        return rc;
    765      }
    766    }
    767  }
    768 
    769  return 0;
    770 }
    771 #endif /* defined(ARCH_USES_GENERIC_SYSCALLS) || defined(__i386__) */
    772 
    773 #if defined(__NR_rename)
    774 /**
    775 * Function responsible for setting up the rename syscall for
    776 * the seccomp filter sandbox.
    777 */
    778 static int
    779 sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    780 {
    781  int rc;
    782  sandbox_cfg_t *elem = NULL;
    783 
    784  // for each dynamic parameter filters
    785  for (elem = filter; elem != NULL; elem = elem->next) {
    786    smp_param_t *param = elem->param;
    787 
    788    if (param != NULL && param->prot == 1 &&
    789        param->syscall == SCMP_SYS(rename)) {
    790 
    791      rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename),
    792            SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value),
    793            SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2));
    794      if (rc != 0) {
    795        log_err(LD_BUG,"(Sandbox) failed to add rename syscall, received "
    796            "libseccomp error %d", rc);
    797        return rc;
    798      }
    799    }
    800  }
    801 
    802  return 0;
    803 }
    804 #elif defined(__NR_renameat)
    805 /**
    806 * Function responsible for setting up the renameat syscall for
    807 * the seccomp filter sandbox.
    808 */
    809 static int
    810 sb_renameat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    811 {
    812  int rc;
    813  sandbox_cfg_t *elem = NULL;
    814 
    815  // for each dynamic parameter filters
    816  for (elem = filter; elem != NULL; elem = elem->next) {
    817    smp_param_t *param = elem->param;
    818 
    819    if (param != NULL && param->prot == 1 &&
    820        param->syscall == SCMP_SYS(renameat)) {
    821 
    822      rc = seccomp_rule_add_4(ctx, SCMP_ACT_ALLOW, SCMP_SYS(renameat),
    823            SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
    824            SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
    825            SCMP_CMP_LOWER32_EQ(2, AT_FDCWD),
    826            SCMP_CMP_STR(3, SCMP_CMP_EQ, param->value2));
    827      if (rc != 0) {
    828        log_err(LD_BUG,"(Sandbox) failed to add renameat syscall, received "
    829            "libseccomp error %d", rc);
    830        return rc;
    831      }
    832    }
    833  }
    834 
    835  return 0;
    836 }
    837 #else
    838 /**
    839 * Function responsible for setting up the renameat2 syscall for
    840 * the seccomp filter sandbox.
    841 */
    842 static int
    843 sb_renameat2(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    844 {
    845  int rc;
    846  sandbox_cfg_t *elem = NULL;
    847 
    848  // for each dynamic parameter filters
    849  for (elem = filter; elem != NULL; elem = elem->next) {
    850    smp_param_t *param = elem->param;
    851 
    852    if (param != NULL && param->prot == 1 &&
    853        param->syscall == SCMP_SYS(renameat2)) {
    854 
    855      rc = seccomp_rule_add_5(ctx, SCMP_ACT_ALLOW, SCMP_SYS(renameat2),
    856            SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
    857            SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
    858            SCMP_CMP_LOWER32_EQ(2, AT_FDCWD),
    859            SCMP_CMP_STR(3, SCMP_CMP_EQ, param->value2),
    860            SCMP_CMP(4, SCMP_CMP_EQ, 0));
    861      if (rc != 0) {
    862        log_err(LD_BUG,"(Sandbox) failed to add renameat2 syscall, received "
    863            "libseccomp error %d", rc);
    864        return rc;
    865      }
    866    }
    867  }
    868 
    869  return 0;
    870 }
    871 #endif /* defined(__NR_rename) || defined(__NR_renameat) */
    872 
    873 /* If Tor is built with fragile hardening for an architecture that uses Linux's
    874 * generic syscall interface a rule allowing the "openat" syscall without
    875 * restriction will have already been added by sb_open(), so there is no need
    876 * to consider adding additional, more restrictive rules here as they will
    877 * simply be ignored.
    878 *
    879 * Also, since the "open" syscall is not defined on these architectures, glibc
    880 * will necessarily use "openat" for its implementation of opendir() as well.
    881 * This means neither of the following two functions will have any effect and
    882 * both can be omitted. */
    883 #if !(defined(ENABLE_FRAGILE_HARDENING) && defined(ARCH_USES_GENERIC_SYSCALLS))
    884 /**
    885 * Function responsible for setting up the openat syscall for
    886 * the seccomp filter sandbox.
    887 */
    888 static int
    889 sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    890 {
    891  int rc;
    892  sandbox_cfg_t *elem = NULL;
    893 
    894  // for each dynamic parameter filters
    895  for (elem = filter; elem != NULL; elem = elem->next) {
    896    smp_param_t *param = elem->param;
    897 
    898    if (param != NULL && param->prot == 1 && param->syscall
    899        == SCMP_SYS(openat)) {
    900      rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
    901          SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
    902          SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
    903          SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
    904              O_CLOEXEC));
    905      if (rc != 0) {
    906        log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
    907            "libseccomp error %d", rc);
    908        return rc;
    909      }
    910    }
    911  }
    912 
    913  return 0;
    914 }
    915 
    916 static int
    917 sb_opendir(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    918 {
    919  int rc;
    920  sandbox_cfg_t *elem = NULL;
    921 
    922  // for each dynamic parameter filters
    923  for (elem = filter; elem != NULL; elem = elem->next) {
    924    smp_param_t *param = elem->param;
    925 
    926    if (param != NULL && param->prot == 1 && param->syscall
    927        == PHONY_OPENDIR_SYSCALL) {
    928      rc = allow_file_open(ctx, libc_uses_openat_for_opendir(), param->value);
    929      if (rc != 0) {
    930        log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received "
    931            "libseccomp error %d", rc);
    932        return rc;
    933      }
    934    }
    935  }
    936 
    937  return 0;
    938 }
    939 #endif /* !(defined(ENABLE_FRAGILE_HARDENING) &&
    940            defined(ARCH_USES_GENERIC_SYSCALLS)) */
    941 
    942 #ifdef ENABLE_FRAGILE_HARDENING
    943 /**
    944 * Function responsible for setting up the ptrace syscall for
    945 * the seccomp filter sandbox.
    946 */
    947 static int
    948 sb_ptrace(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    949 {
    950  int rc;
    951  pid_t pid = getpid();
    952  (void) filter;
    953 
    954  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace),
    955      SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_ATTACH),
    956      SCMP_CMP(1, SCMP_CMP_EQ, pid));
    957  if (rc)
    958    return rc;
    959 
    960  /* AddressSanitizer uses "PTRACE_GETREGSET" on AArch64 (ARM64) and
    961   * System/390, "PTRACE_GETREGS" everywhere else. */
    962 #if defined(__aarch64__) || defined(__s390__)
    963  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace),
    964      SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_GETREGSET),
    965      SCMP_CMP(1, SCMP_CMP_EQ, pid));
    966 #else
    967  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace),
    968      SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_GETREGS),
    969      SCMP_CMP(1, SCMP_CMP_EQ, pid));
    970 #endif /* defined(__aarch64__) || defined(__s390__) */
    971  if (rc)
    972    return rc;
    973 
    974  return 0;
    975 }
    976 #endif
    977 
    978 /**
    979 * Function responsible for setting up the socket syscall for
    980 * the seccomp filter sandbox.
    981 */
    982 static int
    983 sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
    984 {
    985  int rc = 0;
    986  int i, j;
    987  (void) filter;
    988 
    989 #ifdef __i386__
    990  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket));
    991  if (rc)
    992    return rc;
    993 #endif
    994 
    995  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
    996      SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
    997      SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM));
    998  if (rc)
    999    return rc;
   1000 
   1001  for (i = 0; i < 2; ++i) {
   1002    const int pf = i ? PF_INET : PF_INET6;
   1003    for (j=0; j < 3; ++j) {
   1004      const int type     = (j == 0) ? SOCK_STREAM :
   1005                                      SOCK_DGRAM;
   1006      const int protocol = (j == 0) ? IPPROTO_TCP :
   1007                           (j == 1) ? IPPROTO_IP :
   1008                                      IPPROTO_UDP;
   1009      rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
   1010        SCMP_CMP(0, SCMP_CMP_EQ, pf),
   1011        SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, type),
   1012        SCMP_CMP(2, SCMP_CMP_EQ, protocol));
   1013      if (rc)
   1014        return rc;
   1015    }
   1016  }
   1017 
   1018 #ifdef ENABLE_NSS
   1019  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
   1020    SCMP_CMP(0, SCMP_CMP_EQ, PF_INET),
   1021    SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM),
   1022    SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP));
   1023  if (rc)
   1024    return rc;
   1025 #endif /* defined(ENABLE_NSS) */
   1026 
   1027  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
   1028      SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
   1029      SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM),
   1030      SCMP_CMP(2, SCMP_CMP_EQ, 0));
   1031  if (rc)
   1032    return rc;
   1033 
   1034  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
   1035      SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX),
   1036      SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_DGRAM),
   1037      SCMP_CMP(2, SCMP_CMP_EQ, 0));
   1038  if (rc)
   1039    return rc;
   1040 
   1041  rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket),
   1042      SCMP_CMP(0, SCMP_CMP_EQ, PF_NETLINK),
   1043      SCMP_CMP_MASKED(1, SOCK_CLOEXEC, SOCK_RAW),
   1044      SCMP_CMP(2, SCMP_CMP_EQ, 0));
   1045  if (rc)
   1046    return rc;
   1047 
   1048  return 0;
   1049 }
   1050 
   1051 /**
   1052 * Function responsible for setting up the socketpair syscall for
   1053 * the seccomp filter sandbox.
   1054 */
   1055 static int
   1056 sb_socketpair(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1057 {
   1058  int rc = 0;
   1059  (void) filter;
   1060 
   1061 #ifdef __i386__
   1062  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair));
   1063  if (rc)
   1064    return rc;
   1065 #endif
   1066 
   1067  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair),
   1068      SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE),
   1069      SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC));
   1070  if (rc)
   1071    return rc;
   1072 
   1073  return 0;
   1074 }
   1075 
   1076 #ifdef HAVE_KIST_SUPPORT
   1077 
   1078 #include <linux/sockios.h>
   1079 
   1080 static int
   1081 sb_ioctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1082 {
   1083  int rc;
   1084  (void) filter;
   1085 
   1086  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl),
   1087                          SCMP_CMP(1, SCMP_CMP_EQ, SIOCOUTQNSD));
   1088  if (rc)
   1089    return rc;
   1090  return 0;
   1091 }
   1092 
   1093 #endif /* defined(HAVE_KIST_SUPPORT) */
   1094 
   1095 /**
   1096 * Function responsible for setting up the setsockopt syscall for
   1097 * the seccomp filter sandbox.
   1098 */
   1099 static int
   1100 sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1101 {
   1102  int rc = 0;
   1103  (void) filter;
   1104 
   1105 #ifdef __i386__
   1106  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt));
   1107  if (rc)
   1108    return rc;
   1109 #endif
   1110 
   1111  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
   1112      SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
   1113      SCMP_CMP(2, SCMP_CMP_EQ, SO_REUSEADDR));
   1114  if (rc)
   1115    return rc;
   1116 
   1117  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
   1118      SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
   1119      SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
   1120  if (rc)
   1121    return rc;
   1122 
   1123  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
   1124      SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
   1125      SCMP_CMP(2, SCMP_CMP_EQ, SO_RCVBUF));
   1126  if (rc)
   1127    return rc;
   1128 
   1129 #ifdef HAVE_SYSTEMD
   1130  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
   1131      SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
   1132      SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUFFORCE));
   1133  if (rc)
   1134    return rc;
   1135 #endif /* defined(HAVE_SYSTEMD) */
   1136 
   1137 #ifdef IP_TRANSPARENT
   1138  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
   1139      SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
   1140      SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT));
   1141  if (rc)
   1142    return rc;
   1143 #endif /* defined(IP_TRANSPARENT) */
   1144 
   1145 #ifdef IPV6_V6ONLY
   1146  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
   1147      SCMP_CMP(1, SCMP_CMP_EQ, IPPROTO_IPV6),
   1148      SCMP_CMP(2, SCMP_CMP_EQ, IPV6_V6ONLY));
   1149  if (rc)
   1150    return rc;
   1151 #endif /* defined(IPV6_V6ONLY) */
   1152 
   1153 #ifdef IP_BIND_ADDRESS_NO_PORT
   1154  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt),
   1155      SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
   1156      SCMP_CMP(2, SCMP_CMP_EQ, IP_BIND_ADDRESS_NO_PORT));
   1157  if (rc)
   1158    return rc;
   1159 #endif
   1160 
   1161  return 0;
   1162 }
   1163 
   1164 /**
   1165 * Function responsible for setting up the getsockopt syscall for
   1166 * the seccomp filter sandbox.
   1167 */
   1168 static int
   1169 sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1170 {
   1171  int rc = 0;
   1172  (void) filter;
   1173 
   1174 #ifdef __i386__
   1175  rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt));
   1176  if (rc)
   1177    return rc;
   1178 #endif
   1179 
   1180  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
   1181      SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
   1182      SCMP_CMP(2, SCMP_CMP_EQ, SO_ERROR));
   1183  if (rc)
   1184    return rc;
   1185 
   1186  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
   1187      SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
   1188      SCMP_CMP(2, SCMP_CMP_EQ, SO_ACCEPTCONN));
   1189  if (rc)
   1190    return rc;
   1191 
   1192 #ifdef HAVE_SYSTEMD
   1193  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
   1194      SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
   1195      SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF));
   1196  if (rc)
   1197    return rc;
   1198 #endif /* defined(HAVE_SYSTEMD) */
   1199 
   1200 #ifdef HAVE_LINUX_NETFILTER_IPV4_H
   1201  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
   1202      SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
   1203      SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST));
   1204  if (rc)
   1205    return rc;
   1206 #endif /* defined(HAVE_LINUX_NETFILTER_IPV4_H) */
   1207 
   1208 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
   1209  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
   1210      SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6),
   1211      SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST));
   1212  if (rc)
   1213    return rc;
   1214 #endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */
   1215 
   1216 #ifdef HAVE_KIST_SUPPORT
   1217 #include <netinet/tcp.h>
   1218  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt),
   1219      SCMP_CMP(1, SCMP_CMP_EQ, SOL_TCP),
   1220      SCMP_CMP(2, SCMP_CMP_EQ, TCP_INFO));
   1221  if (rc)
   1222    return rc;
   1223 #endif /* defined(HAVE_KIST_SUPPORT) */
   1224 
   1225  return 0;
   1226 }
   1227 
   1228 #ifdef __NR_fcntl64
   1229 /**
   1230 * Function responsible for setting up the fcntl64 syscall for
   1231 * the seccomp filter sandbox.
   1232 */
   1233 static int
   1234 sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1235 {
   1236  int rc = 0;
   1237  (void) filter;
   1238 
   1239  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
   1240      SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL));
   1241  if (rc)
   1242    return rc;
   1243 
   1244  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
   1245      SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL),
   1246      SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK));
   1247  if (rc)
   1248    return rc;
   1249 
   1250  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
   1251      SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD));
   1252  if (rc)
   1253    return rc;
   1254 
   1255  rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64),
   1256      SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD),
   1257      SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC));
   1258  if (rc)
   1259    return rc;
   1260 
   1261  return 0;
   1262 }
   1263 #endif /* defined(__NR_fcntl64) */
   1264 
   1265 /**
   1266 * Function responsible for setting up the epoll_ctl syscall for
   1267 * the seccomp filter sandbox.
   1268 *
   1269 *  Note: basically allows everything but will keep for now..
   1270 */
   1271 static int
   1272 sb_epoll_ctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1273 {
   1274  int rc = 0;
   1275  (void) filter;
   1276 
   1277  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
   1278      SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD));
   1279  if (rc)
   1280    return rc;
   1281 
   1282  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
   1283      SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD));
   1284  if (rc)
   1285    return rc;
   1286 
   1287  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl),
   1288      SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL));
   1289  if (rc)
   1290    return rc;
   1291 
   1292  return 0;
   1293 }
   1294 
   1295 /**
   1296 * Function responsible for setting up the prctl syscall for
   1297 * the seccomp filter sandbox.
   1298 *
   1299 * NOTE: if multiple filters need to be added, the PR_SECCOMP parameter needs
   1300 * to be allowlisted in this function.
   1301 */
   1302 static int
   1303 sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1304 {
   1305  int rc = 0;
   1306  (void) filter;
   1307 
   1308 #ifdef ENABLE_FRAGILE_HARDENING
   1309  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
   1310      SCMP_CMP(0, SCMP_CMP_EQ, PR_GET_DUMPABLE));
   1311  if (rc)
   1312    return rc;
   1313 
   1314  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
   1315      SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_PTRACER));
   1316  if (rc)
   1317    return rc;
   1318 #endif
   1319 
   1320  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl),
   1321      SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE));
   1322  if (rc)
   1323    return rc;
   1324 
   1325  return 0;
   1326 }
   1327 
   1328 /**
   1329 * Function responsible for setting up the mprotect syscall for
   1330 * the seccomp filter sandbox.
   1331 *
   1332 * NOTE: does not NEED to be here.. currently only occurs before filter; will
   1333 * keep just in case for the future.
   1334 */
   1335 static int
   1336 sb_mprotect(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1337 {
   1338  int rc = 0;
   1339  (void) filter;
   1340 
   1341  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
   1342      SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ));
   1343  if (rc)
   1344    return rc;
   1345 
   1346  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
   1347      SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE));
   1348  if (rc)
   1349    return rc;
   1350 
   1351  return 0;
   1352 }
   1353 
   1354 /**
   1355 * Function responsible for setting up the rt_sigprocmask syscall for
   1356 * the seccomp filter sandbox.
   1357 */
   1358 static int
   1359 sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1360 {
   1361  int rc = 0;
   1362  (void) filter;
   1363 
   1364 #if defined(ENABLE_FRAGILE_HARDENING) || \
   1365    defined(USE_TRACING_INSTRUMENTATION_LTTNG)
   1366  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
   1367      SCMP_CMP(0, SCMP_CMP_EQ, SIG_BLOCK));
   1368  if (rc)
   1369    return rc;
   1370 #endif
   1371 
   1372  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
   1373      SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK));
   1374  if (rc)
   1375    return rc;
   1376 
   1377  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask),
   1378      SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK));
   1379  if (rc)
   1380    return rc;
   1381 
   1382  return 0;
   1383 }
   1384 
   1385 /**
   1386 * Function responsible for setting up the flock syscall for
   1387 * the seccomp filter sandbox.
   1388 *
   1389 *  NOTE: does not need to be here, occurs before filter is applied.
   1390 */
   1391 static int
   1392 sb_flock(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1393 {
   1394  int rc = 0;
   1395  (void) filter;
   1396 
   1397  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
   1398      SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB));
   1399  if (rc)
   1400    return rc;
   1401 
   1402  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock),
   1403      SCMP_CMP(1, SCMP_CMP_EQ, LOCK_UN));
   1404  if (rc)
   1405    return rc;
   1406 
   1407  return 0;
   1408 }
   1409 
   1410 /**
   1411 * Function responsible for setting up the futex syscall for
   1412 * the seccomp filter sandbox.
   1413 */
   1414 static int
   1415 sb_futex(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1416 {
   1417  int rc = 0;
   1418  (void) filter;
   1419 
   1420  // can remove
   1421  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
   1422      SCMP_CMP(1, SCMP_CMP_EQ,
   1423          FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME));
   1424  if (rc)
   1425    return rc;
   1426 
   1427  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
   1428      SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
   1429  if (rc)
   1430    return rc;
   1431 
   1432  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex),
   1433      SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE));
   1434  if (rc)
   1435    return rc;
   1436 
   1437  return 0;
   1438 }
   1439 
   1440 /**
   1441 * Function responsible for setting up the mremap syscall for
   1442 * the seccomp filter sandbox.
   1443 *
   1444 *  NOTE: so far only occurs before filter is applied.
   1445 */
   1446 static int
   1447 sb_mremap(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1448 {
   1449  int rc = 0;
   1450  (void) filter;
   1451 
   1452  rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap),
   1453      SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE));
   1454  if (rc)
   1455    return rc;
   1456 
   1457  return 0;
   1458 }
   1459 
   1460 #ifdef ARCH_USES_GENERIC_SYSCALLS
   1461 /**
   1462 * Function responsible for setting up the newfstatat syscall for
   1463 * the seccomp filter sandbox.
   1464 */
   1465 static int
   1466 sb_newfstatat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1467 {
   1468  int rc = 0;
   1469 
   1470  sandbox_cfg_t *elem = NULL;
   1471 
   1472  // for each dynamic parameter filters
   1473  for (elem = filter; elem != NULL; elem = elem->next) {
   1474    smp_param_t *param = elem->param;
   1475 
   1476    if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
   1477        || param->syscall == PHONY_OPENDIR_SYSCALL
   1478        || param->syscall == SCMP_SYS(newfstatat))) {
   1479      rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat),
   1480          SCMP_CMP_LOWER32_EQ(0, AT_FDCWD),
   1481          SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value));
   1482      if (rc != 0) {
   1483        log_err(LD_BUG,"(Sandbox) failed to add newfstatat syscall, received "
   1484            "libseccomp error %d", rc);
   1485        return rc;
   1486      }
   1487    }
   1488  }
   1489 
   1490  return 0;
   1491 }
   1492 #endif /* defined(ARCH_USES_GENERIC_SYSCALLS) */
   1493 
   1494 #ifdef __NR_stat64
   1495 /**
   1496 * Function responsible for setting up the stat64 syscall for
   1497 * the seccomp filter sandbox.
   1498 */
   1499 static int
   1500 sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1501 {
   1502  int rc = 0;
   1503  sandbox_cfg_t *elem = NULL;
   1504 
   1505  // for each dynamic parameter filters
   1506  for (elem = filter; elem != NULL; elem = elem->next) {
   1507    smp_param_t *param = elem->param;
   1508 
   1509    if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
   1510        || param->syscall == SCMP_SYS(stat64))) {
   1511      rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64),
   1512          SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
   1513      if (rc != 0) {
   1514        log_err(LD_BUG,"(Sandbox) failed to add stat64 syscall, received "
   1515            "libseccomp error %d", rc);
   1516        return rc;
   1517      }
   1518    }
   1519  }
   1520 
   1521  return 0;
   1522 }
   1523 #endif /* defined(__NR_stat64) */
   1524 
   1525 static int
   1526 sb_kill(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   1527 {
   1528  (void) filter;
   1529 #ifdef __NR_kill
   1530  /* Allow killing anything with signal 0 -- it isn't really a kill. */
   1531  return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(kill),
   1532       SCMP_CMP(1, SCMP_CMP_EQ, 0));
   1533 #else
   1534  return 0;
   1535 #endif /* defined(__NR_kill) */
   1536 }
   1537 
   1538 /**
   1539 * Array of function pointers responsible for filtering different syscalls at
   1540 * a parameter level.
   1541 */
   1542 static sandbox_filter_func_t filter_func[] = {
   1543    sb_rt_sigaction,
   1544    sb_rt_sigprocmask,
   1545 #ifdef __NR_time
   1546    sb_time,
   1547 #endif
   1548    sb_accept4,
   1549 #ifdef __NR_mmap2
   1550    sb_mmap2,
   1551 #endif
   1552 #if defined(ARCH_USES_GENERIC_SYSCALLS)
   1553    sb_fchownat,
   1554 #elif defined(__i386__)
   1555    sb_chown32,
   1556 #else
   1557    sb_chown,
   1558 #endif
   1559 #if defined(ARCH_USES_GENERIC_SYSCALLS)
   1560    sb_fchmodat,
   1561 #else
   1562    sb_chmod,
   1563 #endif
   1564    sb_open,
   1565 #if !(defined(ENABLE_FRAGILE_HARDENING) && defined(ARCH_USES_GENERIC_SYSCALLS))
   1566    sb_openat,
   1567    sb_opendir,
   1568 #endif
   1569 #ifdef ENABLE_FRAGILE_HARDENING
   1570    sb_ptrace,
   1571 #endif
   1572 #if defined(__NR_rename)
   1573    sb_rename,
   1574 #elif defined(__NR_renameat)
   1575    sb_renameat,
   1576 #else
   1577    sb_renameat2,
   1578 #endif
   1579 #ifdef __NR_fcntl64
   1580    sb_fcntl64,
   1581 #endif
   1582    sb_epoll_ctl,
   1583    sb_prctl,
   1584    sb_mprotect,
   1585    sb_flock,
   1586    sb_futex,
   1587    sb_mremap,
   1588 #if defined(ARCH_USES_GENERIC_SYSCALLS)
   1589    sb_newfstatat,
   1590 #elif defined(__NR_stat64)
   1591    sb_stat64,
   1592 #endif
   1593 
   1594    sb_socket,
   1595    sb_setsockopt,
   1596    sb_getsockopt,
   1597    sb_socketpair,
   1598 #ifdef HAVE_KIST_SUPPORT
   1599    sb_ioctl,
   1600 #endif
   1601    sb_kill
   1602 };
   1603 
   1604 /**
   1605 * Return the interned (and hopefully sandbox-permitted) string equal
   1606 * to @a str.
   1607 *
   1608 * Return NULL if `str` is NULL, or `str` is not an interned string.
   1609 **/
   1610 const char *
   1611 sandbox_intern_string(const char *str)
   1612 {
   1613  const char *interned = sandbox_get_interned_string(str);
   1614 
   1615  if (sandbox_active && str != NULL && interned == NULL) {
   1616    log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
   1617  }
   1618 
   1619  return interned ? interned : str;
   1620 }
   1621 
   1622 /**
   1623 * Return true if the sandbox is running and we are missing an interned string
   1624 * equal to @a str.
   1625 */
   1626 bool
   1627 sandbox_interned_string_is_missing(const char *str)
   1628 {
   1629  return sandbox_active && sandbox_get_interned_string(str) == NULL;
   1630 }
   1631 
   1632 /**
   1633 * Try to find and return the interned string equal to @a str.
   1634 *
   1635 * If there is no such string, return NULL.
   1636 **/
   1637 static const char *
   1638 sandbox_get_interned_string(const char *str)
   1639 {
   1640  sandbox_cfg_t *elem;
   1641 
   1642  if (str == NULL)
   1643    return NULL;
   1644 
   1645  for (elem = filter_dynamic; elem != NULL; elem = elem->next) {
   1646    smp_param_t *param = elem->param;
   1647 
   1648    if (param->prot) {
   1649      if (!strcmp(str, (char*)(param->value))) {
   1650        return (char*)param->value;
   1651      }
   1652      if (param->value2 && !strcmp(str, (char*)param->value2)) {
   1653        return (char*)param->value2;
   1654      }
   1655    }
   1656  }
   1657 
   1658  return NULL;
   1659 }
   1660 
   1661 /* DOCDOC */
   1662 static int
   1663 prot_strings_helper(strmap_t *locations,
   1664                    char **pr_mem_next_p,
   1665                    size_t *pr_mem_left_p,
   1666                    char **value_p)
   1667 {
   1668  char *param_val;
   1669  size_t param_size;
   1670  void *location;
   1671 
   1672  if (*value_p == 0)
   1673    return 0;
   1674 
   1675  param_val = (char*) *value_p;
   1676  param_size = strlen(param_val) + 1;
   1677  location = strmap_get(locations, param_val);
   1678 
   1679  if (location) {
   1680    // We already interned this string.
   1681    tor_free(param_val);
   1682    *value_p = location;
   1683    return 0;
   1684  } else if (*pr_mem_left_p >= param_size) {
   1685    // copy to protected
   1686    location = *pr_mem_next_p;
   1687    memcpy(location, param_val, param_size);
   1688 
   1689    // re-point el parameter to protected
   1690    tor_free(param_val);
   1691    *value_p = location;
   1692 
   1693    strmap_set(locations, location, location); /* good real estate advice */
   1694 
   1695    // move next available protected memory
   1696    *pr_mem_next_p += param_size;
   1697    *pr_mem_left_p -= param_size;
   1698    return 0;
   1699  } else {
   1700    log_err(LD_BUG,"(Sandbox) insufficient protected memory!");
   1701    return -1;
   1702  }
   1703 }
   1704 
   1705 /**
   1706 * Protects all the strings in the sandbox's parameter list configuration. It
   1707 * works by calculating the total amount of memory required by the parameter
   1708 * list, allocating the memory using mmap, and protecting it from writes with
   1709 * mprotect().
   1710 */
   1711 static int
   1712 prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
   1713 {
   1714  int ret = 0;
   1715  size_t pr_mem_size = 0, pr_mem_left = 0;
   1716  char *pr_mem_next = NULL, *pr_mem_base;
   1717  sandbox_cfg_t *el = NULL;
   1718  strmap_t *locations = NULL;
   1719 
   1720  // get total number of bytes required to mmap. (Overestimate.)
   1721  for (el = cfg; el != NULL; el = el->next) {
   1722    pr_mem_size += strlen((char*) el->param->value) + 1;
   1723    if (el->param->value2)
   1724      pr_mem_size += strlen((char*) el->param->value2) + 1;
   1725  }
   1726 
   1727  // allocate protected memory with MALLOC_MP_LIM canary
   1728  pr_mem_base = (char*) mmap(NULL, MALLOC_MP_LIM + pr_mem_size,
   1729      PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
   1730  if (pr_mem_base == MAP_FAILED) {
   1731    log_err(LD_BUG,"(Sandbox) failed allocate protected memory! mmap: %s",
   1732        strerror(errno));
   1733    ret = -1;
   1734    goto out;
   1735  }
   1736 
   1737  pr_mem_next = pr_mem_base + MALLOC_MP_LIM;
   1738  pr_mem_left = pr_mem_size;
   1739 
   1740  locations = strmap_new();
   1741 
   1742  // change el value pointer to protected
   1743  for (el = cfg; el != NULL; el = el->next) {
   1744    if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
   1745                            &el->param->value) < 0) {
   1746      ret = -2;
   1747      goto out;
   1748    }
   1749    if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left,
   1750                            &el->param->value2) < 0) {
   1751      ret = -2;
   1752      goto out;
   1753    }
   1754    el->param->prot = 1;
   1755  }
   1756 
   1757  // protecting from writes
   1758  if (mprotect(pr_mem_base, MALLOC_MP_LIM + pr_mem_size, PROT_READ)) {
   1759    log_err(LD_BUG,"(Sandbox) failed to protect memory! mprotect: %s",
   1760        strerror(errno));
   1761    ret = -3;
   1762    goto out;
   1763  }
   1764 
   1765  /*
   1766   * Setting sandbox restrictions so the string memory cannot be tampered with
   1767   */
   1768  // no mremap of the protected base address
   1769  ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(mremap),
   1770      SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
   1771  if (ret) {
   1772    log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!");
   1773    goto out;
   1774  }
   1775 
   1776  // no munmap of the protected base address
   1777  ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(munmap),
   1778        SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
   1779  if (ret) {
   1780    log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!");
   1781    goto out;
   1782  }
   1783 
   1784  /*
   1785   * Allow mprotect with PROT_READ|PROT_WRITE because openssl uses it, but
   1786   * never over the memory region used by the protected strings.
   1787   *
   1788   * PROT_READ|PROT_WRITE was originally fully allowed in sb_mprotect(), but
   1789   * had to be removed due to limitation of libseccomp regarding intervals.
   1790   *
   1791   * There is a restriction on how much you can mprotect with R|W up to the
   1792   * size of the canary.
   1793   */
   1794  ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
   1795      SCMP_CMP(0, SCMP_CMP_LT, (intptr_t) pr_mem_base),
   1796      SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
   1797      SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
   1798  if (ret) {
   1799    log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!");
   1800    goto out;
   1801  }
   1802 
   1803  ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
   1804      SCMP_CMP(0, SCMP_CMP_GT, (intptr_t) pr_mem_base + pr_mem_size +
   1805          MALLOC_MP_LIM),
   1806      SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM),
   1807      SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
   1808  if (ret) {
   1809    log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!");
   1810    goto out;
   1811  }
   1812 
   1813 out:
   1814  strmap_free(locations, NULL);
   1815  return ret;
   1816 }
   1817 
   1818 /**
   1819 * Auxiliary function used in order to allocate a sandbox_cfg_t element and set
   1820 * its values according the parameter list. All elements are initialised
   1821 * with the 'prot' field set to false, as the pointer is not protected at this
   1822 * point.
   1823 */
   1824 static sandbox_cfg_t*
   1825 new_element2(int syscall, char *value, char *value2)
   1826 {
   1827  smp_param_t *param = NULL;
   1828 
   1829  sandbox_cfg_t *elem = tor_malloc_zero(sizeof(sandbox_cfg_t));
   1830  param = elem->param = tor_malloc_zero(sizeof(smp_param_t));
   1831 
   1832  param->syscall = syscall;
   1833  param->value = value;
   1834  param->value2 = value2;
   1835  param->prot = 0;
   1836 
   1837  return elem;
   1838 }
   1839 
   1840 static sandbox_cfg_t*
   1841 new_element(int syscall, char *value)
   1842 {
   1843  return new_element2(syscall, value, NULL);
   1844 }
   1845 
   1846 #if defined(ARCH_USES_GENERIC_SYSCALLS)
   1847 #define SCMP_chown SCMP_SYS(fchownat)
   1848 #elif defined(__i386__)
   1849 #define SCMP_chown SCMP_SYS(chown32)
   1850 #else
   1851 #define SCMP_chown SCMP_SYS(chown)
   1852 #endif
   1853 
   1854 #if defined(ARCH_USES_GENERIC_SYSCALLS)
   1855 #define SCMP_chmod SCMP_SYS(fchmodat)
   1856 #else
   1857 #define SCMP_chmod SCMP_SYS(chmod)
   1858 #endif
   1859 
   1860 #if defined(__NR_rename)
   1861 #define SCMP_rename SCMP_SYS(rename)
   1862 #elif defined(__NR_renameat)
   1863 #define SCMP_rename SCMP_SYS(renameat)
   1864 #else
   1865 #define SCMP_rename SCMP_SYS(renameat2)
   1866 #endif
   1867 
   1868 #if defined(ARCH_USES_GENERIC_SYSCALLS)
   1869 #define SCMP_stat SCMP_SYS(newfstatat)
   1870 #elif defined(__NR_stat64)
   1871 #define SCMP_stat SCMP_SYS(stat64)
   1872 #else
   1873 #define SCMP_stat SCMP_SYS(stat)
   1874 #endif
   1875 
   1876 int
   1877 sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
   1878 {
   1879  sandbox_cfg_t *elem = NULL;
   1880 
   1881  elem = new_element(SCMP_stat, file);
   1882 
   1883  elem->next = *cfg;
   1884  *cfg = elem;
   1885 
   1886  return 0;
   1887 }
   1888 
   1889 int
   1890 sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
   1891 {
   1892  sandbox_cfg_t *elem = NULL;
   1893 
   1894  elem = new_element(SCMP_SYS(open), file);
   1895 
   1896  elem->next = *cfg;
   1897  *cfg = elem;
   1898 
   1899  return 0;
   1900 }
   1901 
   1902 int
   1903 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
   1904 {
   1905  sandbox_cfg_t *elem = NULL;
   1906 
   1907  elem = new_element(SCMP_chmod, file);
   1908 
   1909  elem->next = *cfg;
   1910  *cfg = elem;
   1911 
   1912  return 0;
   1913 }
   1914 
   1915 int
   1916 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
   1917 {
   1918  sandbox_cfg_t *elem = NULL;
   1919 
   1920  elem = new_element(SCMP_chown, file);
   1921 
   1922  elem->next = *cfg;
   1923  *cfg = elem;
   1924 
   1925  return 0;
   1926 }
   1927 
   1928 int
   1929 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
   1930 {
   1931  sandbox_cfg_t *elem = NULL;
   1932 
   1933  elem = new_element2(SCMP_rename, file1, file2);
   1934 
   1935  elem->next = *cfg;
   1936  *cfg = elem;
   1937 
   1938  return 0;
   1939 }
   1940 
   1941 int
   1942 sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
   1943 {
   1944  sandbox_cfg_t *elem = NULL;
   1945 
   1946  elem = new_element(SCMP_SYS(openat), file);
   1947 
   1948  elem->next = *cfg;
   1949  *cfg = elem;
   1950 
   1951  return 0;
   1952 }
   1953 
   1954 int
   1955 sandbox_cfg_allow_opendir_dirname(sandbox_cfg_t **cfg, char *dir)
   1956 {
   1957  sandbox_cfg_t *elem = NULL;
   1958 
   1959  elem = new_element(PHONY_OPENDIR_SYSCALL, dir);
   1960 
   1961  elem->next = *cfg;
   1962  *cfg = elem;
   1963 
   1964  return 0;
   1965 }
   1966 
   1967 /**
   1968 * Function responsible for going through the parameter syscall filters and
   1969 * call each function pointer in the list.
   1970 */
   1971 static int
   1972 add_param_filter(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
   1973 {
   1974  unsigned i;
   1975  int rc = 0;
   1976 
   1977  // function pointer
   1978  for (i = 0; i < ARRAY_LENGTH(filter_func); i++) {
   1979    rc = filter_func[i](ctx, cfg);
   1980    if (rc) {
   1981      log_err(LD_BUG,"(Sandbox) failed to add syscall %d, received libseccomp "
   1982          "error %d", i, rc);
   1983      return rc;
   1984    }
   1985  }
   1986 
   1987  return 0;
   1988 }
   1989 
   1990 /**
   1991 * Function responsible of loading the libseccomp syscall filters which do not
   1992 * have parameter filtering.
   1993 */
   1994 static int
   1995 add_noparam_filter(scmp_filter_ctx ctx)
   1996 {
   1997  unsigned i;
   1998  int rc = 0;
   1999 
   2000  // add general filters
   2001  for (i = 0; i < ARRAY_LENGTH(filter_nopar_gen); i++) {
   2002    rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i]);
   2003    if (rc != 0) {
   2004      log_err(LD_BUG,"(Sandbox) failed to add syscall index %d (NR=%d), "
   2005          "received libseccomp error %d", i, filter_nopar_gen[i], rc);
   2006      return rc;
   2007    }
   2008  }
   2009 
   2010  if (is_libc_at_least(2, 33)) {
   2011 #ifdef __NR_newfstatat
   2012    // Libc 2.33 uses this syscall to implement both fstat() and stat().
   2013    //
   2014    // The trouble is that to implement fstat(fd, &st), it calls:
   2015    //     newfstatat(fs, "", &st, AT_EMPTY_PATH)
   2016    // We can't detect this usage in particular, because "" is a pointer
   2017    // we don't control.  And we can't just look for AT_EMPTY_PATH, since
   2018    // AT_EMPTY_PATH only has effect when the path string is empty.
   2019    //
   2020    // So our only solution seems to be allowing all fstatat calls, which
   2021    // means that an attacker can stat() anything on the filesystem. That's
   2022    // not a great solution, but I can't find a better one.
   2023    rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat));
   2024    if (rc != 0) {
   2025      log_err(LD_BUG,"(Sandbox) failed to add newfstatat() syscall; "
   2026          "received libseccomp error %d", rc);
   2027      return rc;
   2028    }
   2029 #elif defined(__NR_fstatat64)
   2030    // On i386, glibc uses fstatat64 instead of newfstatat.
   2031    // This is needed for glob() and stat() operations on 32-bit systems.
   2032    rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstatat64));
   2033    if (rc != 0) {
   2034      log_err(LD_BUG,"(Sandbox) failed to add fstatat64() syscall; "
   2035          "received libseccomp error %d", rc);
   2036      return rc;
   2037    }
   2038 #endif
   2039 #if defined(__i386__) && defined(__NR_statx)
   2040    // On i386 with glibc 2.33+, statx may be used for time64 support.
   2041    // glob() in glibc 2.36+ uses statx for directory traversal.
   2042    rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(statx));
   2043    if (rc != 0) {
   2044      log_err(LD_BUG,"(Sandbox) failed to add statx() syscall; "
   2045          "received libseccomp error %d", rc);
   2046      return rc;
   2047    }
   2048 #endif
   2049  }
   2050 
   2051  return 0;
   2052 }
   2053 
   2054 /**
   2055 * Function responsible for setting up and enabling a global syscall filter.
   2056 * The function is a prototype developed for stage 1 of sandboxing Tor.
   2057 * Returns 0 on success.
   2058 */
   2059 static int
   2060 install_syscall_filter(sandbox_cfg_t* cfg)
   2061 {
   2062  int rc = 0;
   2063  scmp_filter_ctx ctx;
   2064 
   2065  ctx = seccomp_init(SCMP_ACT_ERRNO(EPERM));
   2066  if (ctx == NULL) {
   2067    log_err(LD_BUG,"(Sandbox) failed to initialise libseccomp context");
   2068    rc = -1;
   2069    goto end;
   2070  }
   2071 
   2072  // protecting sandbox parameter strings
   2073  if ((rc = prot_strings(ctx, cfg))) {
   2074    goto end;
   2075  }
   2076 
   2077  // add parameter filters
   2078  if ((rc = add_param_filter(ctx, cfg))) {
   2079    log_err(LD_BUG, "(Sandbox) failed to add param filters!");
   2080    goto end;
   2081  }
   2082 
   2083  // adding filters with no parameters
   2084  if ((rc = add_noparam_filter(ctx))) {
   2085    log_err(LD_BUG, "(Sandbox) failed to add param filters!");
   2086    goto end;
   2087  }
   2088 
   2089  // loading the seccomp2 filter
   2090  if ((rc = seccomp_load(ctx))) {
   2091    log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)! "
   2092            "Are you sure that your kernel has seccomp2 support? The "
   2093            "sandbox won't work without it.", rc,
   2094            strerror(-rc));
   2095    goto end;
   2096  }
   2097 
   2098  // marking the sandbox as active
   2099  sandbox_active = 1;
   2100 
   2101 end:
   2102  seccomp_release(ctx);
   2103  return (rc < 0 ? -rc : rc);
   2104 }
   2105 
   2106 #ifdef SYSCALL_NAME_DEBUGGING
   2107 #include "lib/sandbox/linux_syscalls.inc"
   2108 
   2109 /** Return a string containing the name of a given syscall (if we know it) */
   2110 static const char *
   2111 get_syscall_name(int syscall_num)
   2112 {
   2113  int i;
   2114  for (i = 0; SYSCALLS_BY_NUMBER[i].syscall_name; ++i) {
   2115    if (SYSCALLS_BY_NUMBER[i].syscall_num == syscall_num)
   2116      return SYSCALLS_BY_NUMBER[i].syscall_name;
   2117  }
   2118 
   2119  {
   2120     static char syscall_name_buf[64];
   2121     format_dec_number_sigsafe(syscall_num,
   2122                               syscall_name_buf, sizeof(syscall_name_buf));
   2123     return syscall_name_buf;
   2124  }
   2125 }
   2126 
   2127 /** Return the syscall number from a ucontext_t that we got in a signal
   2128 * handler (if we know how to do that). */
   2129 static int
   2130 get_syscall_from_ucontext(const ucontext_t *ctx)
   2131 {
   2132  return (int) ctx->uc_mcontext.M_SYSCALL;
   2133 }
   2134 #else /* !defined(SYSCALL_NAME_DEBUGGING) */
   2135 static const char *
   2136 get_syscall_name(int syscall_num)
   2137 {
   2138  (void) syscall_num;
   2139  return "unknown";
   2140 }
   2141 static int
   2142 get_syscall_from_ucontext(const ucontext_t *ctx)
   2143 {
   2144  (void) ctx;
   2145  return -1;
   2146 }
   2147 #endif /* defined(SYSCALL_NAME_DEBUGGING) */
   2148 
   2149 #ifdef USE_BACKTRACE
   2150 #define MAX_DEPTH 256
   2151 static void *syscall_cb_buf[MAX_DEPTH];
   2152 #endif
   2153 
   2154 /**
   2155 * Function called when a SIGSYS is caught by the application. It notifies the
   2156 * user that an error has occurred and either terminates or allows the
   2157 * application to continue execution, based on the DEBUGGING_CLOSE symbol.
   2158 */
   2159 static void
   2160 sigsys_debugging(int nr, siginfo_t *info, void *void_context)
   2161 {
   2162  ucontext_t *ctx = (ucontext_t *) (void_context);
   2163  const char *syscall_name;
   2164 #ifdef USE_BACKTRACE
   2165  size_t depth;
   2166  int n_fds, i;
   2167  const int *fds = NULL;
   2168 #endif
   2169 
   2170  (void) nr;
   2171 
   2172  if (info->si_code != SYS_SECCOMP)
   2173    return;
   2174 
   2175  if (!ctx)
   2176    return;
   2177 
   2178  int syscall = get_syscall_from_ucontext(ctx);
   2179 
   2180 #ifdef USE_BACKTRACE
   2181  depth = backtrace(syscall_cb_buf, MAX_DEPTH);
   2182  /* Clean up the top stack frame so we get the real function
   2183   * name for the most recently failing function. */
   2184  clean_backtrace(syscall_cb_buf, depth, ctx);
   2185 #endif /* defined(USE_BACKTRACE) */
   2186 
   2187  syscall_name = get_syscall_name(syscall);
   2188 
   2189  tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
   2190                      syscall_name,
   2191                      ")\n",
   2192                      NULL);
   2193 
   2194 #ifdef USE_BACKTRACE
   2195  n_fds = tor_log_get_sigsafe_err_fds(&fds);
   2196  for (i=0; i < n_fds; ++i)
   2197    backtrace_symbols_fd(syscall_cb_buf, (int)depth, fds[i]);
   2198 #endif
   2199 
   2200 #if defined(DEBUGGING_CLOSE)
   2201  _exit(1); // exit ok: programming error has led to sandbox failure.
   2202 #endif // DEBUGGING_CLOSE
   2203 }
   2204 
   2205 /**
   2206 * Function that adds a handler for SIGSYS, which is the signal thrown
   2207 * when the application is issuing a syscall which is not allowed. The
   2208 * main purpose of this function is to help with debugging by identifying
   2209 * filtered syscalls.
   2210 */
   2211 static int
   2212 install_sigsys_debugging(void)
   2213 {
   2214  struct sigaction act;
   2215  sigset_t mask;
   2216 
   2217  memset(&act, 0, sizeof(act));
   2218  sigemptyset(&mask);
   2219  sigaddset(&mask, SIGSYS);
   2220 
   2221  act.sa_sigaction = &sigsys_debugging;
   2222  act.sa_flags = SA_SIGINFO;
   2223  if (sigaction(SIGSYS, &act, NULL) < 0) {
   2224    log_err(LD_BUG,"(Sandbox) Failed to register SIGSYS signal handler");
   2225    return -1;
   2226  }
   2227 
   2228  if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
   2229    log_err(LD_BUG,"(Sandbox) Failed call to sigprocmask()");
   2230    return -2;
   2231  }
   2232 
   2233  return 0;
   2234 }
   2235 
   2236 /**
   2237 * Function responsible of registering the sandbox_cfg_t list of parameter
   2238 * syscall filters to the existing parameter list. This is used for incipient
   2239 * multiple-sandbox support.
   2240 */
   2241 static int
   2242 register_cfg(sandbox_cfg_t* cfg)
   2243 {
   2244  sandbox_cfg_t *elem = NULL;
   2245 
   2246  if (filter_dynamic == NULL) {
   2247    filter_dynamic = cfg;
   2248    return 0;
   2249  }
   2250 
   2251  for (elem = filter_dynamic; elem->next != NULL; elem = elem->next)
   2252    ;
   2253 
   2254  elem->next = cfg;
   2255 
   2256  return 0;
   2257 }
   2258 
   2259 #endif /* defined(USE_LIBSECCOMP) */
   2260 
   2261 #ifdef USE_LIBSECCOMP
   2262 /**
   2263 * Initialises the syscall sandbox filter for any linux architecture, taking
   2264 * into account various available features for different linux flavours.
   2265 */
   2266 static int
   2267 initialise_libseccomp_sandbox(sandbox_cfg_t* cfg)
   2268 {
   2269  /* Prevent glibc from trying to open /dev/tty on fatal error */
   2270  setenv("LIBC_FATAL_STDERR_", "1", 1);
   2271 
   2272  if (install_sigsys_debugging())
   2273    return -1;
   2274 
   2275  if (install_syscall_filter(cfg))
   2276    return -2;
   2277 
   2278  if (register_cfg(cfg))
   2279    return -3;
   2280 
   2281  return 0;
   2282 }
   2283 
   2284 int
   2285 sandbox_is_active(void)
   2286 {
   2287  return sandbox_active != 0;
   2288 }
   2289 #endif /* defined(USE_LIBSECCOMP) */
   2290 
   2291 sandbox_cfg_t*
   2292 sandbox_cfg_new(void)
   2293 {
   2294  return NULL;
   2295 }
   2296 
   2297 int
   2298 sandbox_init(sandbox_cfg_t *cfg)
   2299 {
   2300 #if defined(USE_LIBSECCOMP)
   2301  return initialise_libseccomp_sandbox(cfg);
   2302 
   2303 #elif defined(__linux__)
   2304  (void)cfg;
   2305  log_warn(LD_GENERAL,
   2306           "This version of Tor was built without support for sandboxing. To "
   2307           "build with support for sandboxing on Linux, you must have "
   2308           "libseccomp and its necessary header files (e.g. seccomp.h).");
   2309  return 0;
   2310 
   2311 #else
   2312  (void)cfg;
   2313  log_warn(LD_GENERAL,
   2314           "Currently, sandboxing is only implemented on Linux. The feature "
   2315           "is disabled on your platform.");
   2316  return 0;
   2317 #endif /* defined(USE_LIBSECCOMP) || ... */
   2318 }
   2319 
   2320 #ifndef USE_LIBSECCOMP
   2321 int
   2322 sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
   2323 {
   2324  (void)cfg; (void)file;
   2325  return 0;
   2326 }
   2327 
   2328 int
   2329 sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
   2330 {
   2331  (void)cfg; (void)file;
   2332  return 0;
   2333 }
   2334 
   2335 int
   2336 sandbox_cfg_allow_opendir_dirname(sandbox_cfg_t **cfg, char *dir)
   2337 {
   2338  (void)cfg; (void)dir;
   2339  return 0;
   2340 }
   2341 
   2342 int
   2343 sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
   2344 {
   2345  (void)cfg; (void)file;
   2346  return 0;
   2347 }
   2348 
   2349 int
   2350 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file)
   2351 {
   2352  (void)cfg; (void)file;
   2353  return 0;
   2354 }
   2355 
   2356 int
   2357 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file)
   2358 {
   2359  (void)cfg; (void)file;
   2360  return 0;
   2361 }
   2362 
   2363 int
   2364 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
   2365 {
   2366  (void)cfg; (void)file1; (void)file2;
   2367  return 0;
   2368 }
   2369 
   2370 int
   2371 sandbox_is_active(void)
   2372 {
   2373  return 0;
   2374 }
   2375 
   2376 #endif /* !defined(USE_LIBSECCOMP) */