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

Side by Side Diff: sandbox/linux/seccomp-bpf/sandbox_bpf.h

Issue 10833044: Refactored ErrorCode into it's own class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased after we moved the unittest framework into its own CL Created 8 years, 3 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef SANDBOX_BPF_H__ 5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
6 #define SANDBOX_BPF_H__ 6 #define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
7 7
8 #include <endian.h> 8 #include <endian.h>
9 #include <errno.h> 9 #include <errno.h>
10 #include <fcntl.h> 10 #include <fcntl.h>
11 #include <linux/audit.h> 11 #include <linux/audit.h>
12 #include <linux/filter.h> 12 #include <linux/filter.h>
13 // #include <linux/seccomp.h> 13 // #include <linux/seccomp.h>
14 #include <linux/unistd.h> 14 #include <linux/unistd.h>
15 #include <netinet/in.h> 15 #include <netinet/in.h>
16 #include <netinet/tcp.h> 16 #include <netinet/tcp.h>
(...skipping 21 matching lines...) Expand all
38 #include <map> 38 #include <map>
39 #include <utility> 39 #include <utility>
40 #include <vector> 40 #include <vector>
41 41
42 #ifndef SECCOMP_BPF_STANDALONE 42 #ifndef SECCOMP_BPF_STANDALONE
43 #include "base/basictypes.h" 43 #include "base/basictypes.h"
44 #include "base/eintr_wrapper.h" 44 #include "base/eintr_wrapper.h"
45 #include "base/logging.h" 45 #include "base/logging.h"
46 #endif 46 #endif
47 47
48 #if defined(SECCOMP_BPF_VALGRIND_HACKS)
49 #ifndef SECCOMP_BPF_STANDALONE
50 #include "base/third_party/valgrind/valgrind.h"
51 #endif
52 #endif
53
54
48 // The Seccomp2 kernel ABI is not part of older versions of glibc. 55 // The Seccomp2 kernel ABI is not part of older versions of glibc.
49 // As we can't break compilation with these versions of the library, 56 // As we can't break compilation with these versions of the library,
50 // we explicitly define all missing symbols. 57 // we explicitly define all missing symbols.
51 58
52 #ifndef PR_SET_NO_NEW_PRIVS 59 #ifndef PR_SET_NO_NEW_PRIVS
53 #define PR_SET_NO_NEW_PRIVS 38 60 #define PR_SET_NO_NEW_PRIVS 38
54 #define PR_GET_NO_NEW_PRIVS 39 61 #define PR_GET_NO_NEW_PRIVS 39
55 #endif 62 #endif
56 #ifndef IPC_64 63 #ifndef IPC_64
57 #define IPC_64 0x0100 64 #define IPC_64 0x0100
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) 145 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3)
139 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) 146 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4)
140 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) 147 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5)
141 148
142 #else 149 #else
143 #error Unsupported target platform 150 #error Unsupported target platform
144 151
145 #endif 152 #endif
146 153
147 #include "sandbox/linux/seccomp-bpf/die.h" 154 #include "sandbox/linux/seccomp-bpf/die.h"
155 #include "sandbox/linux/seccomp-bpf/errorcode.h"
148 156
157 namespace playground2 {
149 158
150 struct arch_seccomp_data { 159 struct arch_seccomp_data {
151 int nr; 160 int nr;
152 uint32_t arch; 161 uint32_t arch;
153 uint64_t instruction_pointer; 162 uint64_t instruction_pointer;
154 uint64_t args[6]; 163 uint64_t args[6];
155 }; 164 };
156 165
157 struct arch_sigsys { 166 struct arch_sigsys {
158 void *ip; 167 void *ip;
159 int nr; 168 int nr;
160 unsigned int arch; 169 unsigned int arch;
161 }; 170 };
162 171
163 #ifdef SECCOMP_BPF_STANDALONE 172 #if defined(SECCOMP_BPF_STANDALONE)
164 #define arraysize(x) sizeof(x)/sizeof(*(x))) 173 #define arraysize(x) sizeof(x)/sizeof(*(x)))
165 #define HANDLE_EINTR TEMP_FAILURE_RETRY 174 #define HANDLE_EINTR TEMP_FAILURE_RETRY
166 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 175 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
167 TypeName(); \ 176 TypeName(); \
168 TypeName(const TypeName&); \ 177 TypeName(const TypeName&); \
169 void operator=(const TypeName&) 178 void operator=(const TypeName&)
170 #endif 179 #endif
171 180
172
173 namespace playground2 {
174
175 class Sandbox { 181 class Sandbox {
176 public: 182 public:
177 enum SandboxStatus { 183 enum SandboxStatus {
178 STATUS_UNKNOWN, // Status prior to calling supportsSeccompSandbox() 184 STATUS_UNKNOWN, // Status prior to calling supportsSeccompSandbox()
179 STATUS_UNSUPPORTED, // The kernel does not appear to support sandboxing 185 STATUS_UNSUPPORTED, // The kernel does not appear to support sandboxing
180 STATUS_UNAVAILABLE, // Currently unavailable but might work again later 186 STATUS_UNAVAILABLE, // Currently unavailable but might work again later
181 STATUS_AVAILABLE, // Sandboxing is available but not currently active 187 STATUS_AVAILABLE, // Sandboxing is available but not currently active
182 STATUS_ENABLED // The sandbox is now active 188 STATUS_ENABLED // The sandbox is now active
183 }; 189 };
184 190
185 enum {
186 SB_INVALID = -1,
187 SB_ALLOWED = 0x0000,
188 SB_INSPECT_ARG_1 = 0x8001,
189 SB_INSPECT_ARG_2 = 0x8002,
190 SB_INSPECT_ARG_3 = 0x8004,
191 SB_INSPECT_ARG_4 = 0x8008,
192 SB_INSPECT_ARG_5 = 0x8010,
193 SB_INSPECT_ARG_6 = 0x8020
194 };
195
196 // TrapFnc is a pointer to a function that handles Seccomp traps in 191 // TrapFnc is a pointer to a function that handles Seccomp traps in
197 // user-space. The seccomp policy can request that a trap handler gets 192 // user-space. The seccomp policy can request that a trap handler gets
198 // installed; it does so by returning a suitable ErrorCode() from the 193 // installed; it does so by returning a suitable ErrorCode() from the
199 // syscallEvaluator. See the ErrorCode() constructor for how to pass in 194 // syscallEvaluator. See the ErrorCode() constructor for how to pass in
200 // the function pointer. 195 // the function pointer.
201 // Please note that TrapFnc is executed from signal context and must be 196 // Please note that TrapFnc is executed from signal context and must be
202 // async-signal safe: 197 // async-signal safe:
203 // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html 198 // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
204 typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux); 199 typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux);
205 200
206 class ErrorCode {
207 friend class Sandbox;
208 public:
209 // We can either wrap a symbolic ErrorCode (i.e. enum values), an errno
210 // value (in the range 1..4095), or a pointer to a TrapFnc callback
211 // handling a SECCOMP_RET_TRAP trap.
212 // All of these different values are stored in the "err_" field. So, code
213 // that is using the ErrorCode class typically operates on a single 32bit
214 // field.
215 // This is not only quiet efficient, it also makes the API really easy to
216 // use.
217 ErrorCode(int err = SB_INVALID)
218 : id_(0),
219 fnc_(NULL),
220 aux_(NULL) {
221 switch (err) {
222 case SB_INVALID:
223 err_ = SECCOMP_RET_INVALID;
224 break;
225 case SB_ALLOWED:
226 err_ = SECCOMP_RET_ALLOW;
227 break;
228 case SB_INSPECT_ARG_1...SB_INSPECT_ARG_6:
229 SANDBOX_DIE("Not implemented");
230 break;
231 case 1 ... 4095:
232 err_ = SECCOMP_RET_ERRNO + err;
233 break;
234 default:
235 SANDBOX_DIE("Invalid use of ErrorCode object");
236 }
237 }
238
239 // If we are wrapping a callback, we must assign a unique id. This id is
240 // how the kernel tells us which one of our different SECCOMP_RET_TRAP
241 // cases has been triggered.
242 // The getTrapId() function assigns one unique id (starting at 1) for
243 // each distinct pair of TrapFnc and auxiliary data.
244 ErrorCode(TrapFnc fnc, const void *aux, int id = 0) :
245 id_(id ? id : getTrapId(fnc, aux)),
246 fnc_(fnc),
247 aux_(const_cast<void *>(aux)),
248 err_(SECCOMP_RET_TRAP + id_) {
249 }
250
251 // Destructor doesn't need to do anything.
252 ~ErrorCode() { }
253
254 // Always return the value that goes into the BPF filter program.
255 operator uint32_t() const { return err_; }
256
257 protected:
258 // Fields needed for SECCOMP_RET_TRAP callbacks
259 int id_;
260 TrapFnc fnc_;
261 void *aux_;
262
263 // 32bit field used for all possible types of ErrorCode values
264 uint32_t err_;
265 };
266
267 enum Operation { 201 enum Operation {
268 OP_NOP, OP_EQUAL, OP_NOTEQUAL, OP_LESS, 202 OP_NOP, OP_EQUAL, OP_NOTEQUAL, OP_LESS,
269 OP_LESS_EQUAL, OP_GREATER, OP_GREATER_EQUAL, 203 OP_LESS_EQUAL, OP_GREATER, OP_GREATER_EQUAL,
270 OP_HAS_BITS, OP_DOES_NOT_HAVE_BITS 204 OP_HAS_BITS, OP_DOES_NOT_HAVE_BITS
271 }; 205 };
272 206
273 struct Constraint { 207 struct Constraint {
274 bool is32bit; 208 bool is32bit;
275 Operation op; 209 Operation op;
276 uint32_t value; 210 uint32_t value;
(...skipping 27 matching lines...) Expand all
304 // of system call argument(s) by returning a suitable combination of 238 // of system call argument(s) by returning a suitable combination of
305 // SB_INSPECT_ARG_x bits. 239 // SB_INSPECT_ARG_x bits.
306 // The system argument evaluator is called (if needed) to query additional 240 // The system argument evaluator is called (if needed) to query additional
307 // constraints for the system call arguments. In the vast majority of 241 // constraints for the system call arguments. In the vast majority of
308 // cases, it will set a "Constraint" that forces a new "errno" value. 242 // cases, it will set a "Constraint" that forces a new "errno" value.
309 // But for more complex filters, it is possible to return another mask 243 // But for more complex filters, it is possible to return another mask
310 // of SB_INSPECT_ARG_x bits. 244 // of SB_INSPECT_ARG_x bits.
311 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, 245 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator,
312 EvaluateArguments argumentEvaluator); 246 EvaluateArguments argumentEvaluator);
313 247
248 // We can use ErrorCode to request calling of a trap handler. This method
249 // performs the required wrapping of the callback function into an
250 // ErrorCode object.
251 static ErrorCode Trap(ErrorCode::TrapFnc fnc, const void *aux);
jln (very slow on Chromium) 2012/08/31 01:16:00 I find this name confusing. Maybe GetTrapErrorCode
252
253 // Kill the program and print an error message.
254 static ErrorCode Kill(const char *msg);
jln (very slow on Chromium) 2012/08/31 01:16:00 Same here?
255
314 // This is the main public entry point. It finds all system calls that 256 // This is the main public entry point. It finds all system calls that
315 // need rewriting, sets up the resources needed by the sandbox, and 257 // need rewriting, sets up the resources needed by the sandbox, and
316 // enters Seccomp mode. 258 // enters Seccomp mode.
317 static void startSandbox() { startSandboxInternal(false); } 259 static void startSandbox() { startSandboxInternal(false); }
318 260
319 protected:
320 // Get a file descriptor pointing to "/proc", if currently available.
321 static int getProcFd() { return proc_fd_; }
322
323 private: 261 private:
262 friend class ErrorCode;
324 friend class Util; 263 friend class Util;
325 friend class Verifier; 264 friend class Verifier;
265
266
326 struct Range { 267 struct Range {
327 Range(uint32_t f, uint32_t t, const ErrorCode& e) : 268 Range(uint32_t f, uint32_t t, const ErrorCode& e) :
328 from(f), 269 from(f),
329 to(t), 270 to(t),
330 err(e) { 271 err(e) {
331 } 272 }
332 uint32_t from, to; 273 uint32_t from, to;
333 ErrorCode err; 274 ErrorCode err;
334 }; 275 };
335 struct FixUp { 276 struct FixUp {
336 FixUp(unsigned int a, bool j) : 277 FixUp(unsigned int a, bool j) :
337 jt(j), addr(a) { } 278 jt(j), addr(a) { }
338 bool jt:1; 279 bool jt:1;
339 unsigned addr:31; 280 unsigned addr:31;
340 }; 281 };
341 typedef std::vector<Range> Ranges; 282 typedef std::vector<Range> Ranges;
342 typedef std::map<uint32_t, std::vector<FixUp> > RetInsns; 283 typedef std::map<uint32_t, std::vector<FixUp> > RetInsns;
343 typedef std::vector<struct sock_filter> Program; 284 typedef std::vector<struct sock_filter> Program;
285 typedef std::map<uint32_t, ErrorCode> ErrMap;
344 typedef std::vector<ErrorCode> Traps; 286 typedef std::vector<ErrorCode> Traps;
345 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; 287 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds;
346 288
289 // Get a file descriptor pointing to "/proc", if currently available.
290 static int proc_fd() { return proc_fd_; }
291
347 static ErrorCode probeEvaluator(int signo) __attribute__((const)); 292 static ErrorCode probeEvaluator(int signo) __attribute__((const));
348 static void probeProcess(void); 293 static void probeProcess(void);
349 static ErrorCode allowAllEvaluator(int signo); 294 static ErrorCode allowAllEvaluator(int signo);
350 static void tryVsyscallProcess(void); 295 static void tryVsyscallProcess(void);
351 static bool kernelSupportSeccompBPF(int proc_fd); 296 static bool kernelSupportSeccompBPF(int proc_fd);
352 static bool RunFunctionInPolicy(void (*function)(), 297 static bool RunFunctionInPolicy(void (*function)(),
353 EvaluateSyscall syscallEvaluator, 298 EvaluateSyscall syscallEvaluator,
354 int proc_fd); 299 int proc_fd);
355 static void startSandboxInternal(bool quiet); 300 static void startSandboxInternal(bool quiet);
356 static bool isSingleThreaded(int proc_fd); 301 static bool isSingleThreaded(int proc_fd);
302 static bool isDenied(const ErrorCode& code);
357 static bool disableFilesystem(); 303 static bool disableFilesystem();
358 static void policySanityChecks(EvaluateSyscall syscallEvaluator, 304 static void policySanityChecks(EvaluateSyscall syscallEvaluator,
359 EvaluateArguments argumentEvaluator); 305 EvaluateArguments argumentEvaluator);
360 static void installFilter(bool quiet); 306 static void installFilter(bool quiet);
361 static void findRanges(Ranges *ranges); 307 static void findRanges(Ranges *ranges);
362 static void emitJumpStatements(Program *program, RetInsns *rets, 308 static void emitJumpStatements(Program *program, RetInsns *rets,
363 Ranges::const_iterator start, 309 Ranges::const_iterator start,
364 Ranges::const_iterator stop); 310 Ranges::const_iterator stop);
365 static void emitReturnStatements(Program *prog, const RetInsns& rets); 311 static void emitReturnStatements(Program *prog, const RetInsns& rets);
366 static void sigSys(int nr, siginfo_t *info, void *void_context); 312 static void sigSys(int nr, siginfo_t *info, void *void_context);
367 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux); 313 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux);
368 static int getTrapId(TrapFnc fnc, const void *aux); 314 static int getTrapId(TrapFnc fnc, const void *aux);
369 315
370 static SandboxStatus status_; 316 static SandboxStatus status_;
371 static int proc_fd_; 317 static int proc_fd_;
372 static Evaluators evaluators_; 318 static Evaluators evaluators_;
319 static ErrMap errMap_;
373 static Traps *traps_; 320 static Traps *traps_;
374 static TrapIds trapIds_; 321 static TrapIds trapIds_;
375 static ErrorCode *trapArray_; 322 static ErrorCode *trapArray_;
376 static size_t trapArraySize_; 323 static size_t trapArraySize_;
377 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); 324 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox);
378 }; 325 };
379 326
380 } // namespace 327 } // namespace
381 328
382 #endif // SANDBOX_BPF_H__ 329 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698