summaryrefslogtreecommitdiffstats
path: root/security/sandbox/linux/SandboxFilterUtil.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/linux/SandboxFilterUtil.h')
-rw-r--r--security/sandbox/linux/SandboxFilterUtil.h248
1 files changed, 248 insertions, 0 deletions
diff --git a/security/sandbox/linux/SandboxFilterUtil.h b/security/sandbox/linux/SandboxFilterUtil.h
new file mode 100644
index 0000000000..6e9180bb95
--- /dev/null
+++ b/security/sandbox/linux/SandboxFilterUtil.h
@@ -0,0 +1,248 @@
+/* -*- 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
+#else
+# define CASES_FOR_epoll_wait case __NR_epoll_pwait
+#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