| OLD | NEW |
| 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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux); | 264 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux); |
| 265 | 265 |
| 266 // We can use ErrorCode to request calling of a trap handler. This method | 266 // We can use ErrorCode to request calling of a trap handler. This method |
| 267 // performs the required wrapping of the callback function into an | 267 // performs the required wrapping of the callback function into an |
| 268 // ErrorCode object. | 268 // ErrorCode object. |
| 269 // The "aux" field can carry a pointer to arbitrary data. See EvaluateSyscall | 269 // 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() | 270 // for a description of how to pass data from setSandboxPolicy() to a Trap() |
| 271 // handler. | 271 // handler. |
| 272 static ErrorCode Trap(ErrorCode::TrapFnc fnc, const void *aux); | 272 static ErrorCode Trap(ErrorCode::TrapFnc fnc, const void *aux); |
| 273 | 273 |
| 274 // Calls a user-space trap handler and disables all sandboxing for system |
| 275 // calls made from this trap handler. |
| 276 // NOTE: This feature, by definition, disables all security features of |
| 277 // the sandbox. It should never be used in production, but it can be |
| 278 // very useful to diagnose code that is incompatible with the sandbox. |
| 279 // If even a single system call returns "UnsafeTrap", the security of |
| 280 // entire sandbox should be considered compromised. |
| 281 static ErrorCode UnsafeTrap(ErrorCode::TrapFnc fnc, const void *aux); |
| 282 |
| 274 // Kill the program and print an error message. | 283 // Kill the program and print an error message. |
| 275 static ErrorCode Kill(const char *msg); | 284 static ErrorCode Kill(const char *msg); |
| 276 | 285 |
| 277 // This is the main public entry point. It finds all system calls that | 286 // 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 | 287 // need rewriting, sets up the resources needed by the sandbox, and |
| 279 // enters Seccomp mode. | 288 // enters Seccomp mode. |
| 280 static void startSandbox() { startSandboxInternal(false); } | 289 static void startSandbox() { startSandboxInternal(false); } |
| 281 | 290 |
| 282 private: | 291 private: |
| 283 friend class ErrorCode; | 292 friend class ErrorCode; |
| 284 friend class CodeGen; | 293 friend class CodeGen; |
| 285 friend class SandboxUnittestHelper; | 294 friend class SandboxUnittestHelper; |
| 286 friend class Util; | 295 friend class Util; |
| 287 friend class Verifier; | 296 friend class Verifier; |
| 288 | 297 |
| 289 typedef std::vector<struct sock_filter> Program; | 298 typedef std::vector<struct sock_filter> Program; |
| 290 | 299 |
| 291 struct Range { | 300 struct Range { |
| 292 Range(uint32_t f, uint32_t t, const ErrorCode& e) : | 301 Range(uint32_t f, uint32_t t, const ErrorCode& e) |
| 293 from(f), | 302 : from(f), |
| 294 to(t), | 303 to(t), |
| 295 err(e) { | 304 err(e) { |
| 296 } | 305 } |
| 297 uint32_t from, to; | 306 uint32_t from, to; |
| 298 ErrorCode err; | 307 ErrorCode err; |
| 299 }; | 308 }; |
| 309 struct TrapKey { |
| 310 TrapKey(TrapFnc f, const void *a, bool s) |
| 311 : fnc(f), |
| 312 aux(a), |
| 313 safe(s) { |
| 314 } |
| 315 TrapFnc fnc; |
| 316 const void *aux; |
| 317 bool safe; |
| 318 bool operator<(const TrapKey&) const; |
| 319 }; |
| 300 typedef std::vector<Range> Ranges; | 320 typedef std::vector<Range> Ranges; |
| 301 typedef std::map<uint32_t, ErrorCode> ErrMap; | 321 typedef std::map<uint32_t, ErrorCode> ErrMap; |
| 302 typedef std::vector<ErrorCode> Traps; | 322 typedef std::vector<ErrorCode> Traps; |
| 303 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; | 323 typedef std::map<TrapKey, uint16_t> TrapIds; |
| 304 | 324 |
| 305 // Get a file descriptor pointing to "/proc", if currently available. | 325 // Get a file descriptor pointing to "/proc", if currently available. |
| 306 static int proc_fd() { return proc_fd_; } | 326 static int proc_fd() { return proc_fd_; } |
| 307 | 327 |
| 308 static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const)); | 328 static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const)); |
| 309 static void probeProcess(void); | 329 static void probeProcess(void); |
| 310 static ErrorCode allowAllEvaluator(int sysnum, void *aux); | 330 static ErrorCode allowAllEvaluator(int sysnum, void *aux); |
| 311 static void tryVsyscallProcess(void); | 331 static void tryVsyscallProcess(void); |
| 312 static bool kernelSupportSeccompBPF(int proc_fd); | 332 static bool kernelSupportSeccompBPF(int proc_fd); |
| 313 static bool RunFunctionInPolicy(void (*function)(), | 333 static bool RunFunctionInPolicy(void (*function)(), |
| 314 EvaluateSyscall syscallEvaluator, | 334 EvaluateSyscall syscallEvaluator, |
| 315 void *aux, | 335 void *aux, |
| 316 int proc_fd); | 336 int proc_fd); |
| 317 static void startSandboxInternal(bool quiet); | 337 static void startSandboxInternal(bool quiet); |
| 318 static bool isSingleThreaded(int proc_fd); | 338 static bool isSingleThreaded(int proc_fd); |
| 319 static bool isDenied(const ErrorCode& code); | 339 static bool isDenied(const ErrorCode& code); |
| 320 static bool disableFilesystem(); | 340 static bool disableFilesystem(); |
| 321 static void policySanityChecks(EvaluateSyscall syscallEvaluator, | 341 static void policySanityChecks(EvaluateSyscall syscallEvaluator, |
| 322 void *aux); | 342 void *aux); |
| 343 |
| 344 // Function that can be passed as a callback function to CodeGen::Traverse(). |
| 345 // Checks whether the "insn" returns an UnsafeTrap() ErrorCode. If so, it |
| 346 // sets the "bool" variable pointed to by "aux". |
| 347 static void CheckForUnsafeErrorCodes(Instruction *insn, void *aux); |
| 348 |
| 349 // Function that can be passed as a callback function to CodeGen::Traverse(). |
| 350 // Checks whether the "insn" returns an errno value from a BPF filter. If so, |
| 351 // it rewrites the instruction to instead call a Trap() handler that does |
| 352 // the same thing. "aux" is ignored. |
| 353 static void RedirectToUserspace(Instruction *insn, void *aux); |
| 354 |
| 355 // Stackable wrapper around an Evaluators handler. Changes ErrorCodes |
| 356 // returned by a system call evaluator to match the changes made by |
| 357 // RedirectToUserspace(). "aux" should be pointer to wrapped system call |
| 358 // evaluator. |
| 359 static ErrorCode RedirectToUserspaceEvalWrapper(int sysnum, void *aux); |
| 360 |
| 323 static void installFilter(bool quiet); | 361 static void installFilter(bool quiet); |
| 324 static void findRanges(Ranges *ranges); | 362 static void findRanges(Ranges *ranges); |
| 325 static Instruction *assembleJumpTable(CodeGen *gen, | 363 static Instruction *assembleJumpTable(CodeGen *gen, |
| 326 Ranges::const_iterator start, | 364 Ranges::const_iterator start, |
| 327 Ranges::const_iterator stop); | 365 Ranges::const_iterator stop); |
| 328 static void sigSys(int nr, siginfo_t *info, void *void_context); | 366 static void sigSys(int nr, siginfo_t *info, void *void_context); |
| 367 static ErrorCode MakeTrap(ErrorCode::TrapFnc fn, const void *aux, bool safe); |
| 368 |
| 369 // A Trap() handler that returns an "errno" value. The value is encoded |
| 370 // in the "aux" parameter. |
| 371 static intptr_t ReturnErrno(const struct arch_seccomp_data&, void *aux); |
| 372 |
| 329 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux); | 373 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux); |
| 330 static int getTrapId(TrapFnc fnc, const void *aux); | 374 static int getTrapId(TrapFnc fnc, const void *aux); |
| 331 | 375 |
| 332 static SandboxStatus status_; | 376 static SandboxStatus status_; |
| 333 static int proc_fd_; | 377 static int proc_fd_; |
| 334 static Evaluators evaluators_; | 378 static Evaluators evaluators_; |
| 335 static ErrMap errMap_; | |
| 336 static Traps *traps_; | 379 static Traps *traps_; |
| 337 static TrapIds trapIds_; | 380 static TrapIds trapIds_; |
| 338 static ErrorCode *trapArray_; | 381 static ErrorCode *trapArray_; |
| 339 static size_t trapArraySize_; | 382 static size_t trapArraySize_; |
| 383 static bool has_unsafe_traps_; |
| 340 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); | 384 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); |
| 341 }; | 385 }; |
| 342 | 386 |
| 343 } // namespace | 387 } // namespace |
| 344 | 388 |
| 345 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ | 389 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ |
| OLD | NEW |