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/. */
7 #ifndef mozilla_SandboxFilterUtil_h
8 #define mozilla_SandboxFilterUtil_h
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.
15 #include "mozilla/Maybe.h"
16 #include "sandbox/linux/bpf_dsl/policy.h"
17 #include "sandbox/linux/system_headers/linux_syscalls.h"
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.)
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
{
35 using ResultExpr
= sandbox::bpf_dsl::ResultExpr
;
37 virtual ResultExpr
EvaluateSyscall(int aSysno
) const override
;
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 {
45 // Android doesn't use SysV IPC (and doesn't define the selector
46 // constants in its headers), so this isn't implemented there.
48 // aArgShift is the offset to add the argument index when
49 // constructing `Arg` objects: it's 0 for separate syscalls and 1
51 virtual Maybe
<ResultExpr
> EvaluateIpcCall(int aCall
, int aArgShift
) const {
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();
61 } // namespace mozilla
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.)
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.
72 # define CASES_FOR_mmap case __NR_mmap2
74 # define CASES_FOR_mmap case __NR_mmap
78 # define CASES_FOR_fchown \
82 # define CASES_FOR_fchown case __NR_fchown
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: \
93 # define CASES_FOR_getresgid \
94 case __NR_getresgid32: \
96 // The set*id syscalls are omitted; we'll probably never need to allow them.
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
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: \
114 # define CASES_FOR_fstatfs \
115 case __NR_fstatfs64: \
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 \
122 # define CASES_FOR_ftruncate \
123 case __NR_ftruncate: \
124 case __NR_ftruncate64
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
137 // getdents is not like the other FS-related syscalls with a "64" variant
139 # define CASES_FOR_getdents \
140 case __NR_getdents64: \
143 # define CASES_FOR_getdents case __NR_getdents64
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
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
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 \
177 case __NR_ppoll_time64
178 # define CASES_FOR_futex \
180 case __NR_futex_time64
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
190 #if defined(__NR__newselect)
191 # define CASES_FOR_select \
192 case __NR__newselect: \
194 #elif defined(__NR_select)
195 # define CASES_FOR_select \
199 # define CASES_FOR_select CASES_FOR_pselect6
203 # define CASES_FOR_poll \
207 # define CASES_FOR_poll CASES_FOR_ppoll
210 #ifdef __NR_epoll_create
211 # define CASES_FOR_epoll_create \
212 case __NR_epoll_create: \
213 case __NR_epoll_create1
215 # define CASES_FOR_epoll_create case __NR_epoll_create1
218 #ifdef __NR_epoll_wait
219 # define CASES_FOR_epoll_wait \
220 case __NR_epoll_wait: \
221 case __NR_epoll_pwait
223 # define CASES_FOR_epoll_wait case __NR_epoll_pwait
227 # define CASES_FOR_pipe \
231 # define CASES_FOR_pipe case __NR_pipe2
235 # define CASES_FOR_dup2 \
239 # define CASES_FOR_dup2 case __NR_dup3
242 #ifdef __NR_ugetrlimit
243 # define CASES_FOR_getrlimit case __NR_ugetrlimit
245 # define CASES_FOR_getrlimit case __NR_getrlimit
248 #endif // mozilla_SandboxFilterUtil_h