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

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>
Chris Evans 2012/06/01 20:07:55 Remove if it's dead code.
Markus (顧孟勤) 2012/06/01 21:38:52 It's not dead code. It just doesn't work correctly
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_RET_DENY (SECCOMP_RET_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 #define Unsupported target platform
Chris Evans 2012/06/01 20:07:55 Did you mean #error ?
Markus (顧孟勤) 2012/06/01 21:38:52 Doh
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) \
110 (static_cast<int>(sizeof(x)/sizeof(*(x))))
Chris Evans 2012/06/01 20:07:55 A size macro might want to return size_t ?
Markus (顧孟勤) 2012/06/01 21:38:52 Really. Do I have to? It means a million ugly cast
111 #define HANDLE_EINTR TEMP_FAILURE_RETRY
112 #endif
113
114
115 namespace playground2 {
116
117 class Sandbox {
118 friend class Util;
119
120 public:
121 enum ErrorCode {
122 SB_TRAP = -1,
123 SB_ALLOWED = 0x0000,
124 SB_INSPECT_ARG_1 = 0x8001,
125 SB_INSPECT_ARG_2 = 0x8002,
126 SB_INSPECT_ARG_3 = 0x8004,
127 SB_INSPECT_ARG_4 = 0x8008,
128 SB_INSPECT_ARG_5 = 0x8010,
129 SB_INSPECT_ARG_6 = 0x8020
130 };
131
132 enum Operation {
133 OP_NOP, OP_EQUAL, OP_NOTEQUAL, OP_LESS,
134 OP_LESS_EQUAL, OP_GREATER, OP_GREATER_EQUAL,
135 OP_HAS_BITS, OP_DOES_NOT_HAVE_BITS
136 };
137
138 struct Constraint {
139 bool is32bit;
140 Operation op;
141 uint32_t value;
142 ErrorCode passed;
143 ErrorCode failed;
144 };
145
146 typedef ErrorCode (*EvaluateSyscall)(int sysno);
147 typedef int (*EvaluateArguments)(int sysno, int arg,
148 Constraint *constraint);
Chris Evans 2012/06/01 20:07:55 Style: I think Chromium style is to position the p
Chris Evans 2012/06/01 20:07:55 Style: I think Chromium style is to position the p
Markus (顧孟勤) 2012/06/01 21:38:52 This is so broken. And it tends to get painful whe
149
150 // There are a lot of reasons why the Seccomp sandbox might not be available.
151 // This could be because the kernel does not support Seccomp mode, or it
152 // could be because another sandbox is already active.
153 // "proc_fd" should be a file descriptor for "/proc", or -1 if not
154 // provided by the caller.
155 static bool supportsSeccompSandbox(int proc_fd);
156
157 // The sandbox needs to be able to access files in "/proc/self". If this
158 // directory is not accessible when "startSandbox()" gets called, the caller
159 // can provide an already opened file descriptor by calling "setProcFd()".
160 // The sandbox becomes the newer owner of this file descriptor and will
Chris Evans 2012/06/01 20:07:55 Typo: newer -> new ?
Markus (顧孟勤) 2012/06/01 21:38:52 Done.
161 // eventually close it when "startSandbox()" executes.
162 static void setProcFd(int proc_fd);
163
164 // The system call evaluator function is called with the system
165 // call number. It can decide to allow the system call unconditionally
166 // by returning "0"; it can deny the system call unconditionally by
167 // returning an appropriate "errno" value; or it can request inspection
168 // of system call argument(s) by returning a suitable combination of
169 // SB_INSPECT_ARG_x bits.
170 // The system argument evaluator is called (if needed) to query additional
171 // constraints for the system call arguments. In the vast majority of
172 // cases, it will set a "Constraint" that forces a new "errno" value.
173 // But for more complex filters, it is possible to return another mask
174 // of SB_INSPECT_ARG_x bits.
175 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator,
176 EvaluateArguments argumentEvaluator);
177
178 // This is the main public entry point. It finds all system calls that
179 // need rewriting, sets up the resources needed by the sandbox, and
180 // enters Seccomp mode.
181 static void startSandbox();
182
183 protected:
184 // Print an error message and terminate the program. Used for fatal errors.
185 #ifdef SECCOMP_BPF_STANDALONE
186 static void die(const char *msg) __attribute__((noreturn)) {
187 if (msg) {
188 HANDLE_EINTR(write(2, msg, strlen(msg)));
189 HANDLE_EINTR(write(2, "\n", 1));
190 }
191 for (;;) {
Chris Evans 2012/06/01 20:07:55 Why loop infinitely? At least a comment why we're
192 syscall(__NR_exit_group, 1);
193 _exit(1);
194 }
195 }
196 #else
197 #define die(msg) LOG(FATAL) << (msg)
198 #endif
199
200 // Get a file descriptor pointing to "/proc", if currently available.
201 static int getProcFd() { return proc_fd_; }
202
203 private:
204 enum SandboxStatus {
205 STATUS_UNKNOWN, STATUS_UNSUPPORTED, STATUS_AVAILABLE, STATUS_ENABLED
206 };
207
208 static bool isSingleThreaded(int proc_fd);
209 static bool disableFilesystem();
210 static void installFilter();
211 static void sigSys(int nr, siginfo_t *info, void *void_context);
212
213 static SandboxStatus status_;
214 static int proc_fd_;
215 static std::vector<std::pair<EvaluateSyscall,
216 EvaluateArguments> > evaluators_;
217 };
218
219 } // namespace
220
221 #endif // SANDBOX_BPF_H__
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698