Index: sandbox/linux/seccomp_bpf/sandbox_bpf.h |
=================================================================== |
--- sandbox/linux/seccomp_bpf/sandbox_bpf.h (revision 0) |
+++ sandbox/linux/seccomp_bpf/sandbox_bpf.h (revision 0) |
@@ -0,0 +1,218 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef SANDBOX_BPF_H__ |
+#define SANDBOX_BPF_H__ |
+ |
+#include <algorithm> |
+#include <endian.h> |
+#include <errno.h> |
+#include <fcntl.h> |
+#include <linux/audit.h> |
+#include <linux/filter.h> |
+//#include <linux/seccomp.h> |
+#include <linux/unistd.h> |
+#include <netinet/in.h> |
+#include <netinet/tcp.h> |
+#include <netinet/udp.h> |
+#include <sched.h> |
+#include <stddef.h> |
+#include <stdint.h> |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+#include <sys/ioctl.h> |
+#include <sys/ipc.h> |
+#include <sys/mman.h> |
+#include <sys/prctl.h> |
+#include <sys/shm.h> |
+#include <sys/stat.h> |
+#include <sys/types.h> |
+#include <sys/uio.h> |
+#include <sys/wait.h> |
+#include <unistd.h> |
+#include <vector> |
+ |
+#include "util.h" |
+ |
+ |
+// The Seccomp2 kernel ABI is not part of older versions of glibc. |
+// As we can't break compilation with these versions of the library, |
+// we explicitly define all missing symbols. |
+ |
+#ifndef PR_SET_NO_NEW_PRIVS |
+#define PR_SET_NO_NEW_PRIVS 38 |
+#define PR_GET_NO_NEW_PRIVS 39 |
+#endif |
+#ifndef IPC_64 |
+#define IPC_64 0x0100 |
+#endif |
+#ifndef SECCOMP_MODE_FILTER |
+#define SECCOMP_MODE_DISABLED 0 |
+#define SECCOMP_MODE_STRICT 1 |
+#define SECCOMP_MODE_FILTER 2 // User user-supplied filter |
+#define SECCOMP_RET_KILL 0x00000000U // Kill the task immediately |
+#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_ACTION 0xffff0000U // Masks for the return value |
+#define SECCOMP_RET_DATA 0x0000ffffU // sections |
+#endif |
+#define SECCOMP_RET_DENY (SECCOMP_RET_ERRNO|EPERM) |
+#ifndef SYS_SECCOMP |
+#define SYS_SECCOMP 1 |
+#endif |
+ |
+#if defined(__i386__) |
+#define MAX_SYSCALL 512 |
+#define SECCOMP_ARCH AUDIT_ARCH_I386 |
+#define REG_RESULT REG_EAX |
+#define REG_SYSCALL REG_EAX |
+#define REG_PARM1 REG_EBX |
+#define REG_PARM2 REG_ECX |
+#define REG_PARM3 REG_EDX |
+#define REG_PARM4 REG_ESI |
+#define REG_PARM5 REG_EDI |
+#define REG_PARM6 REG_EBP |
+#elif defined(__x86_64__) |
+#define MAX_SYSCALL 512 |
+#define SECCOMP_ARCH AUDIT_ARCH_X86_64 |
+#define REG_RESULT REG_RAX |
+#define REG_SYSCALL REG_RAX |
+#define REG_PARM1 REG_RDI |
+#define REG_PARM2 REG_RSI |
+#define REG_PARM3 REG_RDX |
+#define REG_PARM4 REG_R10 |
+#define REG_PARM5 REG_R8 |
+#define REG_PARM6 REG_R9 |
+#else |
+#define Unsupported target platform |
+#endif |
+ |
+struct arch_seccomp_data { |
+ int nr; |
+ uint32_t arch; |
+ uint64_t instruction_pointer; |
+ uint64_t args[6]; |
+}; |
+ |
+ |
+#define ARRAYSIZE(x) \ |
+ (int)(sizeof(x)/sizeof(*(x))) |
+ |
+ |
+namespace playground2 { |
+ |
+class Sandbox { |
+ friend class Util; |
+ |
+ public: |
+ enum ErrorCode { |
+ SB_TRAP = -1, |
+ SB_ALLOWED = 0x0000, |
+ SB_INSPECT_ARG_1 = 0x8001, |
+ SB_INSPECT_ARG_2 = 0x8002, |
+ SB_INSPECT_ARG_3 = 0x8004, |
+ SB_INSPECT_ARG_4 = 0x8008, |
+ SB_INSPECT_ARG_5 = 0x8010, |
+ SB_INSPECT_ARG_6 = 0x8020 |
+ }; |
+ |
+ 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; |
+ }; |
+ |
+ typedef ErrorCode (*EvaluateSyscall)(int sysno); |
+ typedef int (*EvaluateArguments)(int sysno, int arg, |
+ Constraint *constraint); |
+ |
+ // 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 int supportsSeccompSandbox(int proc_fd) |
+ asm("SupportsSeccomp2Sandbox"); |
+ |
+ // 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()". |
+ // The sandbox becomes the newer owner of this file descriptor and will |
+ // eventually close it when "startSandbox()" executes. |
+ static void setProcFd(int proc_fd) asm("Seccomp2SandboxSetProcFd"); |
+ |
+ // 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() asm("StartSeccomp2Sandbox"); |
+ |
+ // This optional call can be used to provide a non-standard sandbox |
+ // policy. |
+ // The system call evaluator function is called with the system |
+ // call number. It can decide to allow the system call unconditionally |
+ // by returning "0"; it can deny the system call unconditionally by |
+ // returning an appropriate "errno" value; or it can request inspection |
+ // of system call argument(s) by returning a suitable combination of |
+ // SB_INSPECT_ARG_x bits. |
+ // The system argument evaluator is called (if needed) to query additional |
+ // constraints for the system call arguments. In the vast majority of |
+ // cases, it will set a "Constraint" that forces a new "errno" value. |
+ // But for more complex filters, it is possible to return another mask |
+ // of SB_INSPECT_ARG_x bits. |
+ static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, |
+ EvaluateArguments argumentEvaluator); |
+ |
+ protected: |
+ // Print an error message and terminate the program. Used for fatal errors. |
+ static void die(const char *msg = 0) __attribute__((noreturn)) { |
+ if (msg) { |
+ TEMP_FAILURE_RETRY(write(2, msg, strlen(msg))); |
+ TEMP_FAILURE_RETRY(write(2, "\n", 1)); |
+ } |
+ for (;;) { |
+ syscall(__NR_exit_group, 1); |
+ _exit(1); |
+ } |
+ } |
+ |
+ // Get a file descriptor pointing to "/proc", if currently available. |
+ static int getProcFd() { return proc_fd_; } |
+ |
+ private: |
+ enum SandboxStatus { |
+ STATUS_UNKNOWN, STATUS_UNSUPPORTED, STATUS_AVAILABLE, STATUS_ENABLED |
+ }; |
+ |
+ static bool isSingleThreaded(int proc_fd); |
+ static bool disableFilesystem(); |
+ static int jumpTableSize(int numSyscalls, bool recursing = false); |
+ static void verifyJumpTable(struct sock_filter *filter, int numInsn, |
+ const int *syscallList, int numSyscalls); |
+ static int jumpTable(struct sock_filter *filter, int *idx, |
+ const int *syscallList, int numSyscalls, |
+ int ret, bool sorted = false, |
+ bool recursing = false); |
+ static void installFilter(); |
+ static void sigSys(int nr, siginfo_t *info, void *void_context); |
+ |
+ static SandboxStatus status_; |
+ static int proc_fd_; |
+ static std::vector<std::pair<EvaluateSyscall, |
+ EvaluateArguments> > evaluators_; |
+}; |
+ |
+} // namespace |
+ |
+#endif // SANDBOX_BPF_H__ |
Property changes on: sandbox/linux/seccomp_bpf/sandbox_bpf.h |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |