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

Unified Diff: sandbox/linux/seccomp_bpf/sandbox_bpf.h

Issue 10458040: Initial snapshot of the new BPF-enabled seccomp sandbox. This code is (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 months 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
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,234 @@
+// 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 <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 <algorithm>
+#include <utility>
+#include <vector>
+
+#ifndef SECCOMP_BPF_STANDALONE
+#include "base/basictypes.h"
+#include "base/eintr_wrapper.h"
+#include "base/logging.h"
+#endif
+
+// 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_DENY_ERRNO EPERM
+#ifndef SYS_SECCOMP
+#define SYS_SECCOMP 1
+#endif
+
+#if defined(__i386__)
+#define MIN_SYSCALL 0
+#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 MIN_SYSCALL 0
+#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
+#error Unsupported target platform
+#endif
+
+struct arch_seccomp_data {
+ int nr;
+ uint32_t arch;
+ uint64_t instruction_pointer;
+ uint64_t args[6];
+};
+
+#ifdef SECCOMP_BPF_STANDALONE
+#define arraysize(x) sizeof(x)/sizeof(*(x)))
+#define HANDLE_EINTR TEMP_FAILURE_RETRY
+#endif
+
+
+namespace playground2 {
+
+class Sandbox {
+ friend class Util;
+
+ public:
+ enum SandboxStatus {
+ STATUS_UNKNOWN, // Status prior to calling supportsSeccompSandbox()
+ STATUS_UNSUPPORTED, // The kernel does not appear to support sandboxing
+ STATUS_UNAVAILABLE, // Currently unavailable but might work again later
+ STATUS_AVAILABLE, // Sandboxing is available but not currently active
+ STATUS_ENABLED // The sandbox is now active
+ };
+
+ 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 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()".
+ // The sandbox becomes the new owner of this file descriptor and will
+ // eventually close it when "startSandbox()" executes.
+ static void setProcFd(int proc_fd);
+
+ // 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);
+
+ // 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();
+
+ protected:
+ // Print an error message and terminate the program. Used for fatal errors.
+ static void die(const char *msg) __attribute__((noreturn)) {
+ if (!suppressLogging_) {
+#ifdef SECCOMP_BPF_STANDALONE
+ if (msg) {
+ HANDLE_EINTR(write(2, msg, strlen(msg)));
+ HANDLE_EINTR(write(2, "\n", 1));
+ }
+#else
+ LOG(FATAL) << msg;
+#endif
+ }
+ for (;;) {
+ // exit_group() should exit our program. After all, it is defined as a
+ // function that doesn't return. But things can theoretically go wrong.
+ // Especially, since we are dealing with system call filters. Continuing
+ // execution would be very bad in most cases where die() gets called.
+ // So, if there is no way for us to ask for the program to exit, the next
+ // best thing we can do is to loop indefinitely. Maybe, somebody will
+ // notice and file a bug...
+ syscall(__NR_exit_group, 1);
+ _exit(1);
Chris Evans 2012/06/01 22:48:23 Again, seems strange to alternate between syscall(
Markus (顧孟勤) 2012/06/01 23:46:33 It's a last-ditch effort. If for some reason our d
+ }
+ }
+
+ // Get a file descriptor pointing to "/proc", if currently available.
+ static int getProcFd() { return proc_fd_; }
+
+ private:
+ static bool isSingleThreaded(int proc_fd);
+ static bool disableFilesystem();
+ static void installFilter();
+ static void sigSys(int nr, siginfo_t *info, void *void_context);
+
+ static bool suppressLogging_;
+ 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

Powered by Google App Engine
This is Rietveld 408576698