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

Side by Side 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, 6 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 unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef SANDBOX_BPF_H__
6 #define SANDBOX_BPF_H__
7
8 #include <endian.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <linux/audit.h>
12 #include <linux/filter.h>
13 // #include <linux/seccomp.h>
14 #include <linux/unistd.h>
15 #include <netinet/in.h>
16 #include <netinet/tcp.h>
17 #include <netinet/udp.h>
18 #include <sched.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/ioctl.h>
25 #include <sys/ipc.h>
26 #include <sys/mman.h>
27 #include <sys/prctl.h>
28 #include <sys/shm.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <sys/uio.h>
32 #include <sys/wait.h>
33 #include <unistd.h>
34
35 #include <algorithm>
36 #include <utility>
37 #include <vector>
38
39 #ifndef SECCOMP_BPF_STANDALONE
40 #include "base/basictypes.h"
41 #include "base/eintr_wrapper.h"
42 #include "base/logging.h"
43 #endif
44
45 // The Seccomp2 kernel ABI is not part of older versions of glibc.
46 // As we can't break compilation with these versions of the library,
47 // we explicitly define all missing symbols.
48
49 #ifndef PR_SET_NO_NEW_PRIVS
50 #define PR_SET_NO_NEW_PRIVS 38
51 #define PR_GET_NO_NEW_PRIVS 39
52 #endif
53 #ifndef IPC_64
54 #define IPC_64 0x0100
55 #endif
56 #ifndef SECCOMP_MODE_FILTER
57 #define SECCOMP_MODE_DISABLED 0
58 #define SECCOMP_MODE_STRICT 1
59 #define SECCOMP_MODE_FILTER 2 // User user-supplied filter
60 #define SECCOMP_RET_KILL 0x00000000U // Kill the task immediately
61 #define SECCOMP_RET_TRAP 0x00030000U // Disallow and force a SIGSYS
62 #define SECCOMP_RET_ERRNO 0x00050000U // Returns an errno
63 #define SECCOMP_RET_TRACE 0x7ff00000U // Pass to a tracer or disallow
64 #define SECCOMP_RET_ALLOW 0x7fff0000U // Allow
65 #define SECCOMP_RET_ACTION 0xffff0000U // Masks for the return value
66 #define SECCOMP_RET_DATA 0x0000ffffU // sections
67 #endif
68 #define SECCOMP_DENY_ERRNO EPERM
69 #ifndef SYS_SECCOMP
70 #define SYS_SECCOMP 1
71 #endif
72
73 #if defined(__i386__)
74 #define MIN_SYSCALL 0
75 #define MAX_SYSCALL 512
76 #define SECCOMP_ARCH AUDIT_ARCH_I386
77 #define REG_RESULT REG_EAX
78 #define REG_SYSCALL REG_EAX
79 #define REG_PARM1 REG_EBX
80 #define REG_PARM2 REG_ECX
81 #define REG_PARM3 REG_EDX
82 #define REG_PARM4 REG_ESI
83 #define REG_PARM5 REG_EDI
84 #define REG_PARM6 REG_EBP
85 #elif defined(__x86_64__)
86 #define MIN_SYSCALL 0
87 #define MAX_SYSCALL 512
88 #define SECCOMP_ARCH AUDIT_ARCH_X86_64
89 #define REG_RESULT REG_RAX
90 #define REG_SYSCALL REG_RAX
91 #define REG_PARM1 REG_RDI
92 #define REG_PARM2 REG_RSI
93 #define REG_PARM3 REG_RDX
94 #define REG_PARM4 REG_R10
95 #define REG_PARM5 REG_R8
96 #define REG_PARM6 REG_R9
97 #else
98 #error Unsupported target platform
99 #endif
100
101 struct arch_seccomp_data {
102 int nr;
103 uint32_t arch;
104 uint64_t instruction_pointer;
105 uint64_t args[6];
106 };
107
108 #ifdef SECCOMP_BPF_STANDALONE
109 #define arraysize(x) sizeof(x)/sizeof(*(x)))
110 #define HANDLE_EINTR TEMP_FAILURE_RETRY
111 #endif
112
113
114 namespace playground2 {
115
116 class Sandbox {
117 friend class Util;
118
119 public:
120 enum SandboxStatus {
121 STATUS_UNKNOWN, // Status prior to calling supportsSeccompSandbox()
122 STATUS_UNSUPPORTED, // The kernel does not appear to support sandboxing
123 STATUS_UNAVAILABLE, // Currently unavailable but might work again later
124 STATUS_AVAILABLE, // Sandboxing is available but not currently active
125 STATUS_ENABLED // The sandbox is now active
126 };
127
128 enum ErrorCode {
129 SB_TRAP = -1,
130 SB_ALLOWED = 0x0000,
131 SB_INSPECT_ARG_1 = 0x8001,
132 SB_INSPECT_ARG_2 = 0x8002,
133 SB_INSPECT_ARG_3 = 0x8004,
134 SB_INSPECT_ARG_4 = 0x8008,
135 SB_INSPECT_ARG_5 = 0x8010,
136 SB_INSPECT_ARG_6 = 0x8020
137 };
138
139 enum Operation {
140 OP_NOP, OP_EQUAL, OP_NOTEQUAL, OP_LESS,
141 OP_LESS_EQUAL, OP_GREATER, OP_GREATER_EQUAL,
142 OP_HAS_BITS, OP_DOES_NOT_HAVE_BITS
143 };
144
145 struct Constraint {
146 bool is32bit;
147 Operation op;
148 uint32_t value;
149 ErrorCode passed;
150 ErrorCode failed;
151 };
152
153 typedef ErrorCode (*EvaluateSyscall)(int sysno);
154 typedef int (*EvaluateArguments)(int sysno, int arg,
155 Constraint *constraint);
156
157 // There are a lot of reasons why the Seccomp sandbox might not be available.
158 // This could be because the kernel does not support Seccomp mode, or it
159 // could be because another sandbox is already active.
160 // "proc_fd" should be a file descriptor for "/proc", or -1 if not
161 // provided by the caller.
162 static SandboxStatus supportsSeccompSandbox(int proc_fd);
163
164 // The sandbox needs to be able to access files in "/proc/self". If this
165 // directory is not accessible when "startSandbox()" gets called, the caller
166 // can provide an already opened file descriptor by calling "setProcFd()".
167 // The sandbox becomes the new owner of this file descriptor and will
168 // eventually close it when "startSandbox()" executes.
169 static void setProcFd(int proc_fd);
170
171 // The system call evaluator function is called with the system
172 // call number. It can decide to allow the system call unconditionally
173 // by returning "0"; it can deny the system call unconditionally by
174 // returning an appropriate "errno" value; or it can request inspection
175 // of system call argument(s) by returning a suitable combination of
176 // SB_INSPECT_ARG_x bits.
177 // The system argument evaluator is called (if needed) to query additional
178 // constraints for the system call arguments. In the vast majority of
179 // cases, it will set a "Constraint" that forces a new "errno" value.
180 // But for more complex filters, it is possible to return another mask
181 // of SB_INSPECT_ARG_x bits.
182 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator,
183 EvaluateArguments argumentEvaluator);
184
185 // This is the main public entry point. It finds all system calls that
186 // need rewriting, sets up the resources needed by the sandbox, and
187 // enters Seccomp mode.
188 static void startSandbox();
189
190 protected:
191 // Print an error message and terminate the program. Used for fatal errors.
192 static void die(const char *msg) __attribute__((noreturn)) {
193 if (!suppressLogging_) {
194 if (msg) {
195 #ifdef SECCOMP_BPF_STANDALONE
196 HANDLE_EINTR(write(2, msg, strlen(msg)));
197 HANDLE_EINTR(write(2, "\n", 1));
198 #else
199 LOG(FATAL) << msg;
200 #endif
201 }
202 }
203 for (;;) {
204 // exit_group() should exit our program. After all, it is defined as a
205 // function that doesn't return. But things can theoretically go wrong.
206 // Especially, since we are dealing with system call filters. Continuing
207 // execution would be very bad in most cases where die() gets called.
208 // So, if there is no way for us to ask for the program to exit, the next
209 // best thing we can do is to loop indefinitely. Maybe, somebody will
210 // notice and file a bug...
211 syscall(__NR_exit_group, 1);
212 _exit(1);
213 }
214 }
215
216 // Get a file descriptor pointing to "/proc", if currently available.
217 static int getProcFd() { return proc_fd_; }
218
219 private:
220 static bool isSingleThreaded(int proc_fd);
221 static bool disableFilesystem();
222 static void installFilter();
223 static void sigSys(int nr, siginfo_t *info, void *void_context);
224
225 static bool suppressLogging_;
226 static SandboxStatus status_;
227 static int proc_fd_;
228 static std::vector<std::pair<EvaluateSyscall,
229 EvaluateArguments> > evaluators_;
230 };
231
232 } // namespace
233
234 #endif // SANDBOX_BPF_H__
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698