tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SandboxFilterUtil.h (8043B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_SandboxFilterUtil_h
      8 #define mozilla_SandboxFilterUtil_h
      9 
     10 // This header file exists to hold helper code for SandboxFilter.cpp,
     11 // to make that file easier to read for anyone trying to understand
     12 // the filter policy.  It's mostly about smoothing out differences
     13 // between different Linux architectures.
     14 
     15 #include "mozilla/Maybe.h"
     16 #include "sandbox/linux/bpf_dsl/policy.h"
     17 #include "sandbox/linux/system_headers/linux_syscalls.h"
     18 
     19 namespace mozilla {
     20 
     21 // This class handles syscalls for BSD socket and SysV IPC operations.
     22 // On 32-bit x86 they're multiplexed via socketcall(2) and ipc(2),
     23 // respectively; on most other architectures they're individual system
     24 // calls. It translates the syscalls into socketcall/ipc selector
     25 // values, because those are defined (even if not used) for all
     26 // architectures.  (As of kernel 4.2.0, x86 also has regular system
     27 // calls, but userland will typically still use socketcall.)
     28 //
     29 // This EvaluateSyscall() routine always returns InvalidSyscall() for
     30 // everything else.  It's assumed that subclasses will be implementing
     31 // a whitelist policy, so they can handle what they're whitelisting
     32 // and then defer to this class in the default case.
     33 class SandboxPolicyBase : public sandbox::bpf_dsl::Policy {
     34 public:
     35  using ResultExpr = sandbox::bpf_dsl::ResultExpr;
     36 
     37  virtual ResultExpr EvaluateSyscall(int aSysno) const override;
     38 
     39  // aHasArgs is true if this is a normal syscall, where the arguments
     40  // can be inspected by seccomp-bpf, rather than a case of socketcall().
     41  virtual Maybe<ResultExpr> EvaluateSocketCall(int aCall, bool aHasArgs) const {
     42    return Nothing();
     43  }
     44 
     45  // Android doesn't use SysV IPC (and doesn't define the selector
     46  // constants in its headers), so this isn't implemented there.
     47 #ifndef ANDROID
     48  // aArgShift is the offset to add the argument index when
     49  // constructing `Arg` objects: it's 0 for separate syscalls and 1
     50  // for ipc().
     51  virtual Maybe<ResultExpr> EvaluateIpcCall(int aCall, int aArgShift) const {
     52    return Nothing();
     53  }
     54 #endif
     55 
     56  // Returns true if the running kernel supports separate syscalls for
     57  // socket operations, or false if it supports only socketcall(2).
     58  static bool HasSeparateSocketCalls();
     59 };
     60 
     61 }  // namespace mozilla
     62 
     63 // "Machine independent" pseudo-syscall numbers, to deal with arch
     64 // dependencies.  (Most 32-bit archs started with 32-bit off_t; older
     65 // archs started with 16-bit uid_t/gid_t; 32-bit registers can't hold
     66 // a 64-bit offset for mmap; and so on.)
     67 //
     68 // For some of these, the "old" syscalls are also in use in some
     69 // cases; see, e.g., the handling of RT vs. non-RT signal syscalls.
     70 
     71 #ifdef __NR_mmap2
     72 #  define CASES_FOR_mmap case __NR_mmap2
     73 #else
     74 #  define CASES_FOR_mmap case __NR_mmap
     75 #endif
     76 
     77 #ifdef __NR_fchown32
     78 #  define CASES_FOR_fchown \
     79    case __NR_fchown32:    \
     80    case __NR_fchown
     81 #else
     82 #  define CASES_FOR_fchown case __NR_fchown
     83 #endif
     84 
     85 #ifdef __NR_getuid32
     86 #  define CASES_FOR_getuid case __NR_getuid32
     87 #  define CASES_FOR_getgid case __NR_getgid32
     88 #  define CASES_FOR_geteuid case __NR_geteuid32
     89 #  define CASES_FOR_getegid case __NR_getegid32
     90 #  define CASES_FOR_getresuid \
     91    case __NR_getresuid32:    \
     92    case __NR_getresuid
     93 #  define CASES_FOR_getresgid \
     94    case __NR_getresgid32:    \
     95    case __NR_getresgid
     96 // The set*id syscalls are omitted; we'll probably never need to allow them.
     97 #else
     98 #  define CASES_FOR_getuid case __NR_getuid
     99 #  define CASES_FOR_getgid case __NR_getgid
    100 #  define CASES_FOR_geteuid case __NR_geteuid
    101 #  define CASES_FOR_getegid case __NR_getegid
    102 #  define CASES_FOR_getresuid case __NR_getresuid
    103 #  define CASES_FOR_getresgid case __NR_getresgid
    104 #endif
    105 
    106 #ifdef __NR_stat64
    107 #  define CASES_FOR_stat case __NR_stat64
    108 #  define CASES_FOR_lstat case __NR_lstat64
    109 #  define CASES_FOR_fstat case __NR_fstat64
    110 #  define CASES_FOR_fstatat case __NR_fstatat64
    111 #  define CASES_FOR_statfs \
    112    case __NR_statfs64:    \
    113    case __NR_statfs
    114 #  define CASES_FOR_fstatfs \
    115    case __NR_fstatfs64:    \
    116    case __NR_fstatfs
    117 #  define CASES_FOR_fcntl case __NR_fcntl64
    118 // FIXME: we might not need the compat cases for these on non-Android:
    119 #  define CASES_FOR_lseek \
    120    case __NR_lseek:      \
    121    case __NR__llseek
    122 #  define CASES_FOR_ftruncate \
    123    case __NR_ftruncate:      \
    124    case __NR_ftruncate64
    125 #else
    126 #  define CASES_FOR_stat case __NR_stat
    127 #  define CASES_FOR_lstat case __NR_lstat
    128 #  define CASES_FOR_fstatat case __NR_newfstatat
    129 #  define CASES_FOR_fstat case __NR_fstat
    130 #  define CASES_FOR_fstatfs case __NR_fstatfs
    131 #  define CASES_FOR_statfs case __NR_statfs
    132 #  define CASES_FOR_fcntl case __NR_fcntl
    133 #  define CASES_FOR_lseek case __NR_lseek
    134 #  define CASES_FOR_ftruncate case __NR_ftruncate
    135 #endif
    136 
    137 // getdents is not like the other FS-related syscalls with a "64" variant
    138 #ifdef __NR_getdents
    139 #  define CASES_FOR_getdents \
    140    case __NR_getdents64:    \
    141    case __NR_getdents
    142 #else
    143 #  define CASES_FOR_getdents case __NR_getdents64
    144 #endif
    145 
    146 #ifdef __NR_sigprocmask
    147 #  define CASES_FOR_sigprocmask \
    148    case __NR_sigprocmask:      \
    149    case __NR_rt_sigprocmask
    150 #  define CASES_FOR_sigaction \
    151    case __NR_sigaction:      \
    152    case __NR_rt_sigaction
    153 #  define CASES_FOR_sigreturn \
    154    case __NR_sigreturn:      \
    155    case __NR_rt_sigreturn
    156 #else
    157 #  define CASES_FOR_sigprocmask case __NR_rt_sigprocmask
    158 #  define CASES_FOR_sigaction case __NR_rt_sigaction
    159 #  define CASES_FOR_sigreturn case __NR_rt_sigreturn
    160 #endif
    161 
    162 #ifdef __NR_clock_gettime64
    163 #  define CASES_FOR_clock_gettime \
    164    case __NR_clock_gettime:      \
    165    case __NR_clock_gettime64
    166 #  define CASES_FOR_clock_getres \
    167    case __NR_clock_getres:      \
    168    case __NR_clock_getres_time64
    169 #  define CASES_FOR_clock_nanosleep \
    170    case __NR_clock_nanosleep:      \
    171    case __NR_clock_nanosleep_time64
    172 #  define CASES_FOR_pselect6 \
    173    case __NR_pselect6:      \
    174    case __NR_pselect6_time64
    175 #  define CASES_FOR_ppoll \
    176    case __NR_ppoll:      \
    177    case __NR_ppoll_time64
    178 #  define CASES_FOR_futex \
    179    case __NR_futex:      \
    180    case __NR_futex_time64
    181 #else
    182 #  define CASES_FOR_clock_gettime case __NR_clock_gettime
    183 #  define CASES_FOR_clock_getres case __NR_clock_getres
    184 #  define CASES_FOR_clock_nanosleep case __NR_clock_nanosleep
    185 #  define CASES_FOR_pselect6 case __NR_pselect6
    186 #  define CASES_FOR_ppoll case __NR_ppoll
    187 #  define CASES_FOR_futex case __NR_futex
    188 #endif
    189 
    190 #if defined(__NR__newselect)
    191 #  define CASES_FOR_select \
    192    case __NR__newselect:  \
    193      CASES_FOR_pselect6
    194 #elif defined(__NR_select)
    195 #  define CASES_FOR_select \
    196    case __NR_select:      \
    197      CASES_FOR_pselect6
    198 #else
    199 #  define CASES_FOR_select CASES_FOR_pselect6
    200 #endif
    201 
    202 #ifdef __NR_poll
    203 #  define CASES_FOR_poll \
    204    case __NR_poll:      \
    205      CASES_FOR_ppoll
    206 #else
    207 #  define CASES_FOR_poll CASES_FOR_ppoll
    208 #endif
    209 
    210 #ifdef __NR_epoll_create
    211 #  define CASES_FOR_epoll_create \
    212    case __NR_epoll_create:      \
    213    case __NR_epoll_create1
    214 #else
    215 #  define CASES_FOR_epoll_create case __NR_epoll_create1
    216 #endif
    217 
    218 #ifdef __NR_epoll_wait
    219 #  define CASES_FOR_epoll_wait \
    220    case __NR_epoll_wait:      \
    221    case __NR_epoll_pwait:     \
    222    case __NR_epoll_pwait2
    223 #else
    224 #  define CASES_FOR_epoll_wait \
    225    case __NR_epoll_pwait:     \
    226    case __NR_epoll_pwait2
    227 #endif
    228 
    229 #ifdef __NR_pipe
    230 #  define CASES_FOR_pipe \
    231    case __NR_pipe:      \
    232    case __NR_pipe2
    233 #else
    234 #  define CASES_FOR_pipe case __NR_pipe2
    235 #endif
    236 
    237 #ifdef __NR_dup2
    238 #  define CASES_FOR_dup2 \
    239    case __NR_dup2:      \
    240    case __NR_dup3
    241 #else
    242 #  define CASES_FOR_dup2 case __NR_dup3
    243 #endif
    244 
    245 #ifdef __NR_ugetrlimit
    246 #  define CASES_FOR_getrlimit case __NR_ugetrlimit
    247 #else
    248 #  define CASES_FOR_getrlimit case __NR_getrlimit
    249 #endif
    250 
    251 #endif  // mozilla_SandboxFilterUtil_h