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