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