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

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

Issue 11363212: Added support for greylisting of system calls. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added Sandbox::ForwardSyscall() to make error reporting more straight-forward for common cases Created 8 years 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/errorcode.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_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ 5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
6 #define SANDBOX_LINUX_SECCOMP_BPF_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>
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 }; 200 };
201 201
202 // TrapFnc is a pointer to a function that handles Seccomp traps in 202 // TrapFnc is a pointer to a function that handles Seccomp traps in
203 // user-space. The seccomp policy can request that a trap handler gets 203 // user-space. The seccomp policy can request that a trap handler gets
204 // installed; it does so by returning a suitable ErrorCode() from the 204 // installed; it does so by returning a suitable ErrorCode() from the
205 // syscallEvaluator. See the ErrorCode() constructor for how to pass in 205 // syscallEvaluator. See the ErrorCode() constructor for how to pass in
206 // the function pointer. 206 // the function pointer.
207 // Please note that TrapFnc is executed from signal context and must be 207 // Please note that TrapFnc is executed from signal context and must be
208 // async-signal safe: 208 // async-signal safe:
209 // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html 209 // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
210 // Also note that it follows the calling convention of native system calls.
211 // In other words, it reports an error by returning an exit code in the
212 // range -1..-4096. It should not set errno when reporting errors; on the
213 // other hand, accidentally modifying errno is harmless and the changes will
214 // be undone afterwards.
210 typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux); 215 typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux);
211 216
212 enum Operation { 217 enum Operation {
213 OP_NOP, OP_EQUAL, OP_NOTEQUAL, OP_LESS, 218 OP_NOP, OP_EQUAL, OP_NOTEQUAL, OP_LESS,
214 OP_LESS_EQUAL, OP_GREATER, OP_GREATER_EQUAL, 219 OP_LESS_EQUAL, OP_GREATER, OP_GREATER_EQUAL,
215 OP_HAS_BITS, OP_DOES_NOT_HAVE_BITS 220 OP_HAS_BITS, OP_DOES_NOT_HAVE_BITS
216 }; 221 };
217 222
218 struct Constraint { 223 struct Constraint {
219 bool is32bit; 224 bool is32bit;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux); 269 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux);
265 270
266 // We can use ErrorCode to request calling of a trap handler. This method 271 // We can use ErrorCode to request calling of a trap handler. This method
267 // performs the required wrapping of the callback function into an 272 // performs the required wrapping of the callback function into an
268 // ErrorCode object. 273 // ErrorCode object.
269 // The "aux" field can carry a pointer to arbitrary data. See EvaluateSyscall 274 // The "aux" field can carry a pointer to arbitrary data. See EvaluateSyscall
270 // for a description of how to pass data from setSandboxPolicy() to a Trap() 275 // for a description of how to pass data from setSandboxPolicy() to a Trap()
271 // handler. 276 // handler.
272 static ErrorCode Trap(ErrorCode::TrapFnc fnc, const void *aux); 277 static ErrorCode Trap(ErrorCode::TrapFnc fnc, const void *aux);
273 278
279 // Calls a user-space trap handler and disables all sandboxing for system
280 // calls made from this trap handler.
281 // NOTE: This feature, by definition, disables all security features of
282 // the sandbox. It should never be used in production, but it can be
283 // very useful to diagnose code that is incompatible with the sandbox.
284 // If even a single system call returns "UnsafeTrap", the security of
285 // entire sandbox should be considered compromised.
286 static ErrorCode UnsafeTrap(ErrorCode::TrapFnc fnc, const void *aux);
287
288 // From within an UnsafeTrap() it is often useful to be able to execute
289 // the system call that triggered the trap. The ForwardSyscall() method
290 // makes this easy. It is more efficient than calling glibc's syscall()
291 // function, as it avoid the extra round-trip to the signal handler. And
jln (very slow on Chromium) 2012/11/21 01:22:03 I think it's worth explaining a tad more. "It is
292 // it automatically does the correct thing to report kernel-style error
293 // conditions, rather than setting errno. See the comments for TrapFnc for
294 // details.
295 static intptr_t ForwardSyscall(const struct arch_seccomp_data& args);
296
274 // Kill the program and print an error message. 297 // Kill the program and print an error message.
275 static ErrorCode Kill(const char *msg); 298 static ErrorCode Kill(const char *msg);
276 299
277 // This is the main public entry point. It finds all system calls that 300 // This is the main public entry point. It finds all system calls that
278 // need rewriting, sets up the resources needed by the sandbox, and 301 // need rewriting, sets up the resources needed by the sandbox, and
279 // enters Seccomp mode. 302 // enters Seccomp mode.
280 static void startSandbox() { startSandboxInternal(false); } 303 static void startSandbox() { startSandboxInternal(false); }
281 304
282 private: 305 private:
283 friend class ErrorCode; 306 friend class ErrorCode;
284 friend class CodeGen; 307 friend class CodeGen;
285 friend class SandboxUnittestHelper; 308 friend class SandboxUnittestHelper;
286 friend class Util; 309 friend class Util;
287 friend class Verifier; 310 friend class Verifier;
288 311
289 typedef std::vector<struct sock_filter> Program; 312 typedef std::vector<struct sock_filter> Program;
290 313
291 struct Range { 314 struct Range {
292 Range(uint32_t f, uint32_t t, const ErrorCode& e) : 315 Range(uint32_t f, uint32_t t, const ErrorCode& e)
293 from(f), 316 : from(f),
294 to(t), 317 to(t),
295 err(e) { 318 err(e) {
296 } 319 }
297 uint32_t from, to; 320 uint32_t from, to;
298 ErrorCode err; 321 ErrorCode err;
299 }; 322 };
323 struct TrapKey {
324 TrapKey(TrapFnc f, const void *a, bool s)
325 : fnc(f),
326 aux(a),
327 safe(s) {
328 }
329 TrapFnc fnc;
330 const void *aux;
331 bool safe;
332 bool operator<(const TrapKey&) const;
333 };
300 typedef std::vector<Range> Ranges; 334 typedef std::vector<Range> Ranges;
301 typedef std::map<uint32_t, ErrorCode> ErrMap; 335 typedef std::map<uint32_t, ErrorCode> ErrMap;
302 typedef std::vector<ErrorCode> Traps; 336 typedef std::vector<ErrorCode> Traps;
303 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; 337 typedef std::map<TrapKey, uint16_t> TrapIds;
304 338
305 // Get a file descriptor pointing to "/proc", if currently available. 339 // Get a file descriptor pointing to "/proc", if currently available.
306 static int proc_fd() { return proc_fd_; } 340 static int proc_fd() { return proc_fd_; }
307 341
308 static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const)); 342 static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const));
309 static void probeProcess(void); 343 static void probeProcess(void);
310 static ErrorCode allowAllEvaluator(int sysnum, void *aux); 344 static ErrorCode allowAllEvaluator(int sysnum, void *aux);
311 static void tryVsyscallProcess(void); 345 static void tryVsyscallProcess(void);
312 static bool kernelSupportSeccompBPF(int proc_fd); 346 static bool kernelSupportSeccompBPF(int proc_fd);
313 static bool RunFunctionInPolicy(void (*function)(), 347 static bool RunFunctionInPolicy(void (*function)(),
314 EvaluateSyscall syscallEvaluator, 348 EvaluateSyscall syscallEvaluator,
315 void *aux, 349 void *aux,
316 int proc_fd); 350 int proc_fd);
317 static void startSandboxInternal(bool quiet); 351 static void startSandboxInternal(bool quiet);
318 static bool isSingleThreaded(int proc_fd); 352 static bool isSingleThreaded(int proc_fd);
319 static bool isDenied(const ErrorCode& code); 353 static bool isDenied(const ErrorCode& code);
320 static bool disableFilesystem(); 354 static bool disableFilesystem();
321 static void policySanityChecks(EvaluateSyscall syscallEvaluator, 355 static void policySanityChecks(EvaluateSyscall syscallEvaluator,
322 void *aux); 356 void *aux);
357
358 // Function that can be passed as a callback function to CodeGen::Traverse().
359 // Checks whether the "insn" returns an UnsafeTrap() ErrorCode. If so, it
360 // sets the "bool" variable pointed to by "aux".
361 static void CheckForUnsafeErrorCodes(Instruction *insn, void *aux);
362
363 // Function that can be passed as a callback function to CodeGen::Traverse().
364 // Checks whether the "insn" returns an errno value from a BPF filter. If so,
365 // it rewrites the instruction to instead call a Trap() handler that does
366 // the same thing. "aux" is ignored.
367 static void RedirectToUserspace(Instruction *insn, void *aux);
368
369 // Stackable wrapper around an Evaluators handler. Changes ErrorCodes
370 // returned by a system call evaluator to match the changes made by
371 // RedirectToUserspace(). "aux" should be pointer to wrapped system call
372 // evaluator.
373 static ErrorCode RedirectToUserspaceEvalWrapper(int sysnum, void *aux);
374
323 static void installFilter(bool quiet); 375 static void installFilter(bool quiet);
324 static void findRanges(Ranges *ranges); 376 static void findRanges(Ranges *ranges);
325 static Instruction *assembleJumpTable(CodeGen *gen, 377 static Instruction *assembleJumpTable(CodeGen *gen,
326 Ranges::const_iterator start, 378 Ranges::const_iterator start,
327 Ranges::const_iterator stop); 379 Ranges::const_iterator stop);
328 static void sigSys(int nr, siginfo_t *info, void *void_context); 380 static void sigSys(int nr, siginfo_t *info, void *void_context);
381 static ErrorCode MakeTrap(ErrorCode::TrapFnc fn, const void *aux, bool safe);
382
383 // A Trap() handler that returns an "errno" value. The value is encoded
384 // in the "aux" parameter.
385 static intptr_t ReturnErrno(const struct arch_seccomp_data&, void *aux);
386
329 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux); 387 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux);
330 static int getTrapId(TrapFnc fnc, const void *aux); 388 static int getTrapId(TrapFnc fnc, const void *aux);
331 389
332 static SandboxStatus status_; 390 static SandboxStatus status_;
333 static int proc_fd_; 391 static int proc_fd_;
334 static Evaluators evaluators_; 392 static Evaluators evaluators_;
335 static ErrMap errMap_;
336 static Traps *traps_; 393 static Traps *traps_;
337 static TrapIds trapIds_; 394 static TrapIds trapIds_;
338 static ErrorCode *trapArray_; 395 static ErrorCode *trapArray_;
339 static size_t trapArraySize_; 396 static size_t trapArraySize_;
397 static bool has_unsafe_traps_;
340 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); 398 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox);
341 }; 399 };
342 400
343 } // namespace 401 } // namespace
344 402
345 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ 403 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/errorcode.cc ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698