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

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

Issue 10878033: Simplified unit testing of sandboxing code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add missing parameter that suppresses benign error messages Created 8 years, 4 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
« no previous file with comments | « sandbox/linux/seccomp-bpf/die.cc ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_BPF_H__
6 #define SANDBOX_BPF_H__ 6 #define 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>
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2) 137 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2)
138 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) 138 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3)
139 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) 139 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4)
140 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) 140 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5)
141 141
142 #else 142 #else
143 #error Unsupported target platform 143 #error Unsupported target platform
144 144
145 #endif 145 #endif
146 146
147 #include "sandbox/linux/seccomp-bpf/die.h"
148
149
147 struct arch_seccomp_data { 150 struct arch_seccomp_data {
148 int nr; 151 int nr;
149 uint32_t arch; 152 uint32_t arch;
150 uint64_t instruction_pointer; 153 uint64_t instruction_pointer;
151 uint64_t args[6]; 154 uint64_t args[6];
152 }; 155 };
153 156
154 struct arch_sigsys { 157 struct arch_sigsys {
155 void *ip; 158 void *ip;
156 int nr; 159 int nr;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 fnc_(NULL), 219 fnc_(NULL),
217 aux_(NULL) { 220 aux_(NULL) {
218 switch (err) { 221 switch (err) {
219 case SB_INVALID: 222 case SB_INVALID:
220 err_ = SECCOMP_RET_INVALID; 223 err_ = SECCOMP_RET_INVALID;
221 break; 224 break;
222 case SB_ALLOWED: 225 case SB_ALLOWED:
223 err_ = SECCOMP_RET_ALLOW; 226 err_ = SECCOMP_RET_ALLOW;
224 break; 227 break;
225 case SB_INSPECT_ARG_1...SB_INSPECT_ARG_6: 228 case SB_INSPECT_ARG_1...SB_INSPECT_ARG_6:
226 die("Not implemented"); 229 SANDBOX_DIE("Not implemented");
227 break; 230 break;
228 case 1 ... 4095: 231 case 1 ... 4095:
229 err_ = SECCOMP_RET_ERRNO + err; 232 err_ = SECCOMP_RET_ERRNO + err;
230 break; 233 break;
231 default: 234 default:
232 die("Invalid use of ErrorCode object"); 235 SANDBOX_DIE("Invalid use of ErrorCode object");
233 } 236 }
234 } 237 }
235 238
236 // If we are wrapping a callback, we must assign a unique id. This id is 239 // If we are wrapping a callback, we must assign a unique id. This id is
237 // how the kernel tells us which one of our different SECCOMP_RET_TRAP 240 // how the kernel tells us which one of our different SECCOMP_RET_TRAP
238 // cases has been triggered. 241 // cases has been triggered.
239 // The getTrapId() function assigns one unique id (starting at 1) for 242 // The getTrapId() function assigns one unique id (starting at 1) for
240 // each distinct pair of TrapFnc and auxiliary data. 243 // each distinct pair of TrapFnc and auxiliary data.
241 ErrorCode(TrapFnc fnc, const void *aux, int id = 0) : 244 ErrorCode(TrapFnc fnc, const void *aux, int id = 0) :
242 id_(id ? id : getTrapId(fnc, aux)), 245 id_(id ? id : getTrapId(fnc, aux)),
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 // constraints for the system call arguments. In the vast majority of 307 // constraints for the system call arguments. In the vast majority of
305 // cases, it will set a "Constraint" that forces a new "errno" value. 308 // cases, it will set a "Constraint" that forces a new "errno" value.
306 // But for more complex filters, it is possible to return another mask 309 // But for more complex filters, it is possible to return another mask
307 // of SB_INSPECT_ARG_x bits. 310 // of SB_INSPECT_ARG_x bits.
308 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, 311 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator,
309 EvaluateArguments argumentEvaluator); 312 EvaluateArguments argumentEvaluator);
310 313
311 // This is the main public entry point. It finds all system calls that 314 // This is the main public entry point. It finds all system calls that
312 // need rewriting, sets up the resources needed by the sandbox, and 315 // need rewriting, sets up the resources needed by the sandbox, and
313 // enters Seccomp mode. 316 // enters Seccomp mode.
314 static void startSandbox(); 317 static void startSandbox() { startSandboxInternal(false); }
315 318
316 protected: 319 protected:
317 // Print an error message and terminate the program. Used for fatal errors.
318 static void die(const char *msg) __attribute__((noreturn)) {
319 if (msg) {
320 #ifndef SECCOMP_BPF_STANDALONE
321 if (!dryRun_) {
322 // LOG(FATAL) is not neccessarily async-signal safe. It would be
323 // better to always use the code for the SECCOMP_BPF_STANDALONE case.
324 // But that prevents the logging and reporting infrastructure from
325 // picking up sandbox related crashes.
326 // For now, in picking between two evils, we decided in favor of
327 // LOG(FATAL). In the long run, we probably want to rewrite this code
328 // to be async-signal safe.
329 LOG(FATAL) << msg;
330 } else
331 #endif
332 {
333 // If there is no logging infrastructure in place, we just write error
334 // messages to stderr.
335 // We also write to stderr, if we are called in a child process from
336 // supportsSeccompSandbox(). This makes sure we can actually do the
337 // correct logging from the parent process, which is more likely to
338 // have access to logging infrastructure.
339 if (HANDLE_EINTR(write(2, msg, strlen(msg)))) { }
340 if (HANDLE_EINTR(write(2, "\n", 1))) { }
341 }
342 }
343 for (;;) {
344 // exit_group() should exit our program. After all, it is defined as a
345 // function that doesn't return. But things can theoretically go wrong.
346 // Especially, since we are dealing with system call filters. Continuing
347 // execution would be very bad in most cases where die() gets called.
348 // So, if there is no way for us to ask for the program to exit, the next
349 // best thing we can do is to loop indefinitely. Maybe, somebody will
350 // notice and file a bug...
351 syscall(__NR_exit_group, 1);
352 _exit(1);
353 }
354 }
355
356 // Get a file descriptor pointing to "/proc", if currently available. 320 // Get a file descriptor pointing to "/proc", if currently available.
357 static int getProcFd() { return proc_fd_; } 321 static int getProcFd() { return proc_fd_; }
358 322
359 private: 323 private:
360 friend class Util; 324 friend class Util;
361 friend class Verifier; 325 friend class Verifier;
362 struct Range { 326 struct Range {
363 Range(uint32_t f, uint32_t t, const ErrorCode& e) : 327 Range(uint32_t f, uint32_t t, const ErrorCode& e) :
364 from(f), 328 from(f),
365 to(t), 329 to(t),
(...skipping 15 matching lines...) Expand all
381 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; 345 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds;
382 346
383 static ErrorCode probeEvaluator(int signo) __attribute__((const)); 347 static ErrorCode probeEvaluator(int signo) __attribute__((const));
384 static void probeProcess(void); 348 static void probeProcess(void);
385 static ErrorCode allowAllEvaluator(int signo); 349 static ErrorCode allowAllEvaluator(int signo);
386 static void tryVsyscallProcess(void); 350 static void tryVsyscallProcess(void);
387 static bool kernelSupportSeccompBPF(int proc_fd); 351 static bool kernelSupportSeccompBPF(int proc_fd);
388 static bool RunFunctionInPolicy(void (*function)(), 352 static bool RunFunctionInPolicy(void (*function)(),
389 EvaluateSyscall syscallEvaluator, 353 EvaluateSyscall syscallEvaluator,
390 int proc_fd); 354 int proc_fd);
355 static void startSandboxInternal(bool quiet);
391 static bool isSingleThreaded(int proc_fd); 356 static bool isSingleThreaded(int proc_fd);
392 static bool disableFilesystem(); 357 static bool disableFilesystem();
393 static void policySanityChecks(EvaluateSyscall syscallEvaluator, 358 static void policySanityChecks(EvaluateSyscall syscallEvaluator,
394 EvaluateArguments argumentEvaluator); 359 EvaluateArguments argumentEvaluator);
395 static void installFilter(); 360 static void installFilter(bool quiet);
396 static void findRanges(Ranges *ranges); 361 static void findRanges(Ranges *ranges);
397 static void emitJumpStatements(Program *program, RetInsns *rets, 362 static void emitJumpStatements(Program *program, RetInsns *rets,
398 Ranges::const_iterator start, 363 Ranges::const_iterator start,
399 Ranges::const_iterator stop); 364 Ranges::const_iterator stop);
400 static void emitReturnStatements(Program *prog, const RetInsns& rets); 365 static void emitReturnStatements(Program *prog, const RetInsns& rets);
401 static void sigSys(int nr, siginfo_t *info, void *void_context); 366 static void sigSys(int nr, siginfo_t *info, void *void_context);
402 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux); 367 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux);
403 static int getTrapId(TrapFnc fnc, const void *aux); 368 static int getTrapId(TrapFnc fnc, const void *aux);
404 369
405 static bool dryRun_;
406 static SandboxStatus status_; 370 static SandboxStatus status_;
407 static int proc_fd_; 371 static int proc_fd_;
408 static Evaluators evaluators_; 372 static Evaluators evaluators_;
409 static Traps *traps_; 373 static Traps *traps_;
410 static TrapIds trapIds_; 374 static TrapIds trapIds_;
411 static ErrorCode *trapArray_; 375 static ErrorCode *trapArray_;
412 static size_t trapArraySize_; 376 static size_t trapArraySize_;
413 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); 377 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox);
414 }; 378 };
415 379
416 } // namespace 380 } // namespace
417 381
418 #endif // SANDBOX_BPF_H__ 382 #endif // SANDBOX_BPF_H__
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/die.cc ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698