| Index: sandbox/linux/seccomp-bpf/sandbox_bpf.h
|
| diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
|
| index 0e781ea7f4d7bc152e79e20a97ac733ea23f5468..477132585f8b036e4c3ea62b3e5f19b83115d380 100644
|
| --- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h
|
| +++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
|
| @@ -37,17 +37,18 @@
|
| #include <algorithm>
|
| #include <limits>
|
| #include <map>
|
| +#include <set>
|
| #include <utility>
|
| #include <vector>
|
|
|
| -#ifndef SECCOMP_BPF_STANDALONE
|
| +#if !defined(SECCOMP_BPF_STANDALONE)
|
| #include "base/basictypes.h"
|
| #include "base/logging.h"
|
| #include "base/posix/eintr_wrapper.h"
|
| #endif
|
|
|
| #if defined(SECCOMP_BPF_VALGRIND_HACKS)
|
| -#ifndef SECCOMP_BPF_STANDALONE
|
| +#if !defined(SECCOMP_BPF_STANDALONE)
|
| #include "base/third_party/valgrind/valgrind.h"
|
| #endif
|
| #endif
|
| @@ -64,20 +65,32 @@
|
| #ifndef IPC_64
|
| #define IPC_64 0x0100
|
| #endif
|
| +
|
| +// In order to build will older tool chains, we currently have to avoid
|
| +// including <linux/seccomp.h>. Until that can be fixed (if ever). Rely on
|
| +// our own definitions of the seccomp kernel ABI.
|
| #ifndef SECCOMP_MODE_FILTER
|
| #define SECCOMP_MODE_DISABLED 0
|
| #define SECCOMP_MODE_STRICT 1
|
| #define SECCOMP_MODE_FILTER 2 // User user-supplied filter
|
| +#endif
|
| +
|
| +#ifndef SECCOMP_RET_KILL
|
| +// Return values supported for BPF filter programs. Please note that the
|
| +// "illegal" SECCOMP_RET_INVALID is not supported by the kernel, should only
|
| +// ever be used internally, and would result in the kernel killing our process.
|
| #define SECCOMP_RET_KILL 0x00000000U // Kill the task immediately
|
| +#define SECCOMP_RET_INVALID 0x00010000U // Illegal return value
|
| #define SECCOMP_RET_TRAP 0x00030000U // Disallow and force a SIGSYS
|
| #define SECCOMP_RET_ERRNO 0x00050000U // Returns an errno
|
| #define SECCOMP_RET_TRACE 0x7ff00000U // Pass to a tracer or disallow
|
| #define SECCOMP_RET_ALLOW 0x7fff0000U // Allow
|
| -#define SECCOMP_RET_INVALID 0x8f8f8f8fU // Illegal return value
|
| #define SECCOMP_RET_ACTION 0xffff0000U // Masks for the return value
|
| #define SECCOMP_RET_DATA 0x0000ffffU // sections
|
| +#else
|
| +#define SECCOMP_RET_INVALID 0x00010000U // Illegal return value
|
| #endif
|
| -#define SECCOMP_DENY_ERRNO EPERM
|
| +
|
| #ifndef SYS_SECCOMP
|
| #define SYS_SECCOMP 1
|
| #endif
|
| @@ -91,7 +104,7 @@
|
| #define MIN_SYSCALL 0u
|
| #define MAX_PUBLIC_SYSCALL 1024u
|
| #define MAX_SYSCALL MAX_PUBLIC_SYSCALL
|
| -#define SECCOMP_ARCH AUDIT_ARCH_I386
|
| +#define SECCOMP_ARCH AUDIT_ARCH_I386
|
|
|
| #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)])
|
| #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX)
|
| @@ -103,12 +116,22 @@
|
| #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI)
|
| #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI)
|
| #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP)
|
| +#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr))
|
| +#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch))
|
| +#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \
|
| + instruction_pointer) + 4)
|
| +#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \
|
| + instruction_pointer) + 0)
|
| +#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
|
| + 8*(nr) + 4)
|
| +#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
|
| + 8*(nr) + 0)
|
|
|
| #elif defined(__x86_64__)
|
| #define MIN_SYSCALL 0u
|
| #define MAX_PUBLIC_SYSCALL 1024u
|
| #define MAX_SYSCALL MAX_PUBLIC_SYSCALL
|
| -#define SECCOMP_ARCH AUDIT_ARCH_X86_64
|
| +#define SECCOMP_ARCH AUDIT_ARCH_X86_64
|
|
|
| #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)])
|
| #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX)
|
| @@ -120,6 +143,16 @@
|
| #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10)
|
| #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8)
|
| #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9)
|
| +#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr))
|
| +#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch))
|
| +#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \
|
| + instruction_pointer) + 4)
|
| +#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \
|
| + instruction_pointer) + 0)
|
| +#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
|
| + 8*(nr) + 4)
|
| +#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
|
| + 8*(nr) + 0)
|
|
|
| #elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))
|
| // ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|,
|
| @@ -143,15 +176,25 @@
|
| // See </arch/arm/include/asm/sigcontext.h> in the Linux kernel.
|
| #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg)
|
| // ARM EABI syscall convention.
|
| -#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0)
|
| -#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7)
|
| -#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc)
|
| -#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0)
|
| -#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1)
|
| -#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2)
|
| -#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3)
|
| -#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4)
|
| -#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5)
|
| +#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0)
|
| +#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7)
|
| +#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc)
|
| +#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0)
|
| +#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1)
|
| +#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2)
|
| +#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3)
|
| +#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4)
|
| +#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5)
|
| +#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr))
|
| +#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch))
|
| +#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \
|
| + instruction_pointer) + 4)
|
| +#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \
|
| + instruction_pointer) + 0)
|
| +#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
|
| + 8*(nr) + 4)
|
| +#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
|
| + 8*(nr) + 0)
|
|
|
| #else
|
| #error Unsupported target platform
|
| @@ -220,20 +263,6 @@ class Sandbox {
|
| // be undone afterwards.
|
| typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux);
|
|
|
| - enum Operation {
|
| - OP_NOP, OP_EQUAL, OP_NOTEQUAL, OP_LESS,
|
| - OP_LESS_EQUAL, OP_GREATER, OP_GREATER_EQUAL,
|
| - OP_HAS_BITS, OP_DOES_NOT_HAVE_BITS
|
| - };
|
| -
|
| - struct Constraint {
|
| - bool is32bit;
|
| - Operation op;
|
| - uint32_t value;
|
| - ErrorCode passed;
|
| - ErrorCode failed;
|
| - };
|
| -
|
| // When calling setSandboxPolicy(), the caller can provide an arbitrary
|
| // pointer. This pointer will then be forwarded to the sandbox policy
|
| // each time a call is made through an EvaluateSyscall function pointer.
|
| @@ -245,21 +274,21 @@ class Sandbox {
|
| // Checks whether a particular system call number is valid on the current
|
| // architecture. E.g. on ARM there's a non-contiguous range of private
|
| // system calls.
|
| - static bool isValidSyscallNumber(int sysnum);
|
| + static bool IsValidSyscallNumber(int sysnum);
|
|
|
| // There are a lot of reasons why the Seccomp sandbox might not be available.
|
| // This could be because the kernel does not support Seccomp mode, or it
|
| // could be because another sandbox is already active.
|
| // "proc_fd" should be a file descriptor for "/proc", or -1 if not
|
| // provided by the caller.
|
| - static SandboxStatus supportsSeccompSandbox(int proc_fd);
|
| + static SandboxStatus SupportsSeccompSandbox(int proc_fd);
|
|
|
| // The sandbox needs to be able to access files in "/proc/self". If this
|
| // directory is not accessible when "startSandbox()" gets called, the caller
|
| - // can provide an already opened file descriptor by calling "setProcFd()".
|
| + // can provide an already opened file descriptor by calling "set_proc_fd()".
|
| // The sandbox becomes the new owner of this file descriptor and will
|
| // eventually close it when "startSandbox()" executes.
|
| - static void setProcFd(int proc_fd);
|
| + static void set_proc_fd(int proc_fd);
|
|
|
| // The system call evaluator function is called with the system
|
| // call number. It can decide to allow the system call unconditionally
|
| @@ -272,7 +301,7 @@ class Sandbox {
|
| // handler. In this case, of course, the data that is pointed to must remain
|
| // valid for the entire time that Trap() handlers can be called; typically,
|
| // this would be the lifetime of the program.
|
| - static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux);
|
| + static void SetSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux);
|
|
|
| // We can use ErrorCode to request calling of a trap handler. This method
|
| // performs the required wrapping of the callback function into an
|
| @@ -301,18 +330,33 @@ class Sandbox {
|
| // directly suitable as a return value for a trap handler.
|
| static intptr_t ForwardSyscall(const struct arch_seccomp_data& args);
|
|
|
| + // We can also use ErrorCode to request evaluation of a conditional
|
| + // statement based on inspection of system call parameters.
|
| + // This method wrap an ErrorCode object around the conditional statement.
|
| + // Argument "argno" (1..6) will be compared to "value" using comparator
|
| + // "op". If the condition is true "passed" will be returned, otherwise
|
| + // "failed".
|
| + // If "is32bit" is set, the argument must in the range of 0x0..(1u << 32 - 1)
|
| + // If it is outside this range, the sandbox treats the system call just
|
| + // the same as any other ABI violation (i.e. it aborts with an error
|
| + // message).
|
| + static ErrorCode Cond(int argno, ErrorCode::ArgType is_32bit,
|
| + ErrorCode::Operation op,
|
| + uint64_t value, const ErrorCode& passed,
|
| + const ErrorCode& failed);
|
| +
|
| // Kill the program and print an error message.
|
| static ErrorCode Kill(const char *msg);
|
|
|
| // This is the main public entry point. It finds all system calls that
|
| // need rewriting, sets up the resources needed by the sandbox, and
|
| // enters Seccomp mode.
|
| - static void startSandbox() { startSandboxInternal(false); }
|
| + static void StartSandbox() { StartSandboxInternal(false); }
|
|
|
| private:
|
| - friend class ErrorCode;
|
| friend class CodeGen;
|
| friend class SandboxUnittestHelper;
|
| + friend class ErrorCode;
|
| friend class Util;
|
| friend class Verifier;
|
|
|
| @@ -342,24 +386,25 @@ class Sandbox {
|
| typedef std::map<uint32_t, ErrorCode> ErrMap;
|
| typedef std::vector<ErrorCode> Traps;
|
| typedef std::map<TrapKey, uint16_t> TrapIds;
|
| + typedef std::set<ErrorCode, struct ErrorCode::LessThan> Conds;
|
|
|
| // Get a file descriptor pointing to "/proc", if currently available.
|
| static int proc_fd() { return proc_fd_; }
|
|
|
| - static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const));
|
| - static void probeProcess(void);
|
| - static ErrorCode allowAllEvaluator(int sysnum, void *aux);
|
| - static void tryVsyscallProcess(void);
|
| - static bool kernelSupportSeccompBPF(int proc_fd);
|
| + static ErrorCode ProbeEvaluator(int sysnum, void *) __attribute__((const));
|
| + static void ProbeProcess(void);
|
| + static ErrorCode AllowAllEvaluator(int sysnum, void *aux);
|
| + static void TryVsyscallProcess(void);
|
| + static bool KernelSupportSeccompBPF(int proc_fd);
|
| static bool RunFunctionInPolicy(void (*function)(),
|
| - EvaluateSyscall syscallEvaluator,
|
| + EvaluateSyscall syscall_evaluator,
|
| void *aux,
|
| int proc_fd);
|
| - static void startSandboxInternal(bool quiet);
|
| - static bool isSingleThreaded(int proc_fd);
|
| - static bool isDenied(const ErrorCode& code);
|
| - static bool disableFilesystem();
|
| - static void policySanityChecks(EvaluateSyscall syscallEvaluator,
|
| + static void StartSandboxInternal(bool quiet);
|
| + static bool IsSingleThreaded(int proc_fd);
|
| + static bool IsDenied(const ErrorCode& code);
|
| + static bool DisableFilesystem();
|
| + static void PolicySanityChecks(EvaluateSyscall syscall_evaluator,
|
| void *aux);
|
|
|
| // Function that can be passed as a callback function to CodeGen::Traverse().
|
| @@ -379,29 +424,37 @@ class Sandbox {
|
| // evaluator.
|
| static ErrorCode RedirectToUserspaceEvalWrapper(int sysnum, void *aux);
|
|
|
| - static void installFilter(bool quiet);
|
| - static void findRanges(Ranges *ranges);
|
| - static Instruction *assembleJumpTable(CodeGen *gen,
|
| + static void InstallFilter(bool quiet);
|
| + static void FindRanges(Ranges *ranges);
|
| + static Instruction *AssembleJumpTable(CodeGen *gen,
|
| Ranges::const_iterator start,
|
| Ranges::const_iterator stop);
|
| - static void sigSys(int nr, siginfo_t *info, void *void_context);
|
| + static Instruction *RetExpression(CodeGen *gen, const ErrorCode& cond);
|
| + static Instruction *CondExpression(CodeGen *gen, const ErrorCode& cond);
|
| +
|
| + // Returns the fatal ErrorCode that is used to indicate that somebody
|
| + // attempted to pass a 64bit value in a 32bit system call argument.
|
| + static ErrorCode Unexpected64bitArgument();
|
| +
|
| + static void SigSys(int nr, siginfo_t *info, void *void_context);
|
| static ErrorCode MakeTrap(ErrorCode::TrapFnc fn, const void *aux, bool safe);
|
|
|
| // A Trap() handler that returns an "errno" value. The value is encoded
|
| // in the "aux" parameter.
|
| static intptr_t ReturnErrno(const struct arch_seccomp_data&, void *aux);
|
|
|
| - static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux);
|
| - static int getTrapId(TrapFnc fnc, const void *aux);
|
| + static intptr_t BpfFailure(const struct arch_seccomp_data& data, void *aux);
|
|
|
| static SandboxStatus status_;
|
| static int proc_fd_;
|
| static Evaluators evaluators_;
|
| static Traps *traps_;
|
| - static TrapIds trapIds_;
|
| - static ErrorCode *trapArray_;
|
| - static size_t trapArraySize_;
|
| + static TrapIds trap_ids_;
|
| + static ErrorCode *trap_array_;
|
| + static size_t trap_array_size_;
|
| static bool has_unsafe_traps_;
|
| + static Conds conds_;
|
| +
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox);
|
| };
|
|
|
|
|