Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(910)

Unified Diff: sandbox/linux/seccomp-bpf/sandbox_bpf.h

Issue 11411254: SECCOMP-BPF: Added supported for inspection system call arguments from BPF filters. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Another attempt at fixing the rebase Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sandbox/linux/seccomp-bpf/demo.cc ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
};
« no previous file with comments | « sandbox/linux/seccomp-bpf/demo.cc ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698