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

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

Issue 11419121: SECCOMP-BPF: Added support for greylisting of system calls. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed system call forwarding on 32bit architectures Created 8 years, 1 month 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_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
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. In other words, the return value from ForwardSyscall() is
295 // directly suitable as a return value for a trap handler.
296 static intptr_t ForwardSyscall(const struct arch_seccomp_data& args);
297
274 // Kill the program and print an error message. 298 // Kill the program and print an error message.
275 static ErrorCode Kill(const char *msg); 299 static ErrorCode Kill(const char *msg);
276 300
277 // This is the main public entry point. It finds all system calls that 301 // 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 302 // need rewriting, sets up the resources needed by the sandbox, and
279 // enters Seccomp mode. 303 // enters Seccomp mode.
280 static void startSandbox() { startSandboxInternal(false); } 304 static void startSandbox() { startSandboxInternal(false); }
281 305
282 private: 306 private:
283 friend class ErrorCode; 307 friend class ErrorCode;
284 friend class CodeGen; 308 friend class CodeGen;
285 friend class SandboxUnittestHelper; 309 friend class SandboxUnittestHelper;
286 friend class Util; 310 friend class Util;
287 friend class Verifier; 311 friend class Verifier;
288 312
289 typedef std::vector<struct sock_filter> Program; 313 typedef std::vector<struct sock_filter> Program;
290 314
291 struct Range { 315 struct Range {
292 Range(uint32_t f, uint32_t t, const ErrorCode& e) : 316 Range(uint32_t f, uint32_t t, const ErrorCode& e)
293 from(f), 317 : from(f),
294 to(t), 318 to(t),
295 err(e) { 319 err(e) {
296 } 320 }
297 uint32_t from, to; 321 uint32_t from, to;
298 ErrorCode err; 322 ErrorCode err;
299 }; 323 };
324 struct TrapKey {
325 TrapKey(TrapFnc f, const void *a, bool s)
326 : fnc(f),
327 aux(a),
328 safe(s) {
329 }
330 TrapFnc fnc;
331 const void *aux;
332 bool safe;
333 bool operator<(const TrapKey&) const;
334 };
300 typedef std::vector<Range> Ranges; 335 typedef std::vector<Range> Ranges;
301 typedef std::map<uint32_t, ErrorCode> ErrMap; 336 typedef std::map<uint32_t, ErrorCode> ErrMap;
302 typedef std::vector<ErrorCode> Traps; 337 typedef std::vector<ErrorCode> Traps;
303 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; 338 typedef std::map<TrapKey, uint16_t> TrapIds;
304 339
305 // Get a file descriptor pointing to "/proc", if currently available. 340 // Get a file descriptor pointing to "/proc", if currently available.
306 static int proc_fd() { return proc_fd_; } 341 static int proc_fd() { return proc_fd_; }
307 342
308 static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const)); 343 static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const));
309 static void probeProcess(void); 344 static void probeProcess(void);
310 static ErrorCode allowAllEvaluator(int sysnum, void *aux); 345 static ErrorCode allowAllEvaluator(int sysnum, void *aux);
311 static void tryVsyscallProcess(void); 346 static void tryVsyscallProcess(void);
312 static bool kernelSupportSeccompBPF(int proc_fd); 347 static bool kernelSupportSeccompBPF(int proc_fd);
313 static bool RunFunctionInPolicy(void (*function)(), 348 static bool RunFunctionInPolicy(void (*function)(),
314 EvaluateSyscall syscallEvaluator, 349 EvaluateSyscall syscallEvaluator,
315 void *aux, 350 void *aux,
316 int proc_fd); 351 int proc_fd);
317 static void startSandboxInternal(bool quiet); 352 static void startSandboxInternal(bool quiet);
318 static bool isSingleThreaded(int proc_fd); 353 static bool isSingleThreaded(int proc_fd);
319 static bool isDenied(const ErrorCode& code); 354 static bool isDenied(const ErrorCode& code);
320 static bool disableFilesystem(); 355 static bool disableFilesystem();
321 static void policySanityChecks(EvaluateSyscall syscallEvaluator, 356 static void policySanityChecks(EvaluateSyscall syscallEvaluator,
322 void *aux); 357 void *aux);
358
359 // Function that can be passed as a callback function to CodeGen::Traverse().
360 // Checks whether the "insn" returns an UnsafeTrap() ErrorCode. If so, it
361 // sets the "bool" variable pointed to by "aux".
362 static void CheckForUnsafeErrorCodes(Instruction *insn, void *aux);
363
364 // Function that can be passed as a callback function to CodeGen::Traverse().
365 // Checks whether the "insn" returns an errno value from a BPF filter. If so,
366 // it rewrites the instruction to instead call a Trap() handler that does
367 // the same thing. "aux" is ignored.
368 static void RedirectToUserspace(Instruction *insn, void *aux);
369
370 // Stackable wrapper around an Evaluators handler. Changes ErrorCodes
371 // returned by a system call evaluator to match the changes made by
372 // RedirectToUserspace(). "aux" should be pointer to wrapped system call
373 // evaluator.
374 static ErrorCode RedirectToUserspaceEvalWrapper(int sysnum, void *aux);
375
323 static void installFilter(bool quiet); 376 static void installFilter(bool quiet);
324 static void findRanges(Ranges *ranges); 377 static void findRanges(Ranges *ranges);
325 static Instruction *assembleJumpTable(CodeGen *gen, 378 static Instruction *assembleJumpTable(CodeGen *gen,
326 Ranges::const_iterator start, 379 Ranges::const_iterator start,
327 Ranges::const_iterator stop); 380 Ranges::const_iterator stop);
328 static void sigSys(int nr, siginfo_t *info, void *void_context); 381 static void sigSys(int nr, siginfo_t *info, void *void_context);
382 static ErrorCode MakeTrap(ErrorCode::TrapFnc fn, const void *aux, bool safe);
383
384 // A Trap() handler that returns an "errno" value. The value is encoded
385 // in the "aux" parameter.
386 static intptr_t ReturnErrno(const struct arch_seccomp_data&, void *aux);
387
329 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux); 388 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux);
330 static int getTrapId(TrapFnc fnc, const void *aux); 389 static int getTrapId(TrapFnc fnc, const void *aux);
331 390
332 static SandboxStatus status_; 391 static SandboxStatus status_;
333 static int proc_fd_; 392 static int proc_fd_;
334 static Evaluators evaluators_; 393 static Evaluators evaluators_;
335 static ErrMap errMap_;
336 static Traps *traps_; 394 static Traps *traps_;
337 static TrapIds trapIds_; 395 static TrapIds trapIds_;
338 static ErrorCode *trapArray_; 396 static ErrorCode *trapArray_;
339 static size_t trapArraySize_; 397 static size_t trapArraySize_;
398 static bool has_unsafe_traps_;
340 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); 399 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox);
341 }; 400 };
342 401
343 } // namespace 402 } // namespace
344 403
345 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ 404 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698