| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_ERRORCODE_H__ |
| 6 #define SANDBOX_LINUX_SECCOMP_BPF_ERRORCODE_H__ |
| 7 |
| 8 namespace playground2 { |
| 9 |
| 10 struct arch_seccomp_data; |
| 11 |
| 12 // This class holds all the possible values that can returned by a sandbox |
| 13 // policy. |
| 14 // We can either wrap a symbolic ErrorCode (i.e. ERR_XXX enum values), an |
| 15 // errno value (in the range 1..4095), a pointer to a TrapFnc callback |
| 16 // handling a SECCOMP_RET_TRAP trap, or a complex constraint. |
| 17 // All of the commonly used values are stored in the "err_" field. So, code |
| 18 // that is using the ErrorCode class typically operates on a single 32bit |
| 19 // field. |
| 20 class ErrorCode { |
| 21 public: |
| 22 enum { |
| 23 // Allow this system call. |
| 24 ERR_ALLOWED = 0x0000, |
| 25 |
| 26 // Deny the system call with a particular "errno" value. |
| 27 ERR_MIN_ERRNO = 1, |
| 28 ERR_MAX_ERRNO = 4095, |
| 29 |
| 30 // This code should never be used directly, it is used internally only. |
| 31 ERR_INVALID = -1, |
| 32 }; |
| 33 |
| 34 // TrapFnc is a pointer to a function that handles Seccomp traps in |
| 35 // user-space. The seccomp policy can request that a trap handler gets |
| 36 // installed; it does so by returning a suitable ErrorCode() from the |
| 37 // syscallEvaluator. See the ErrorCode() constructor for how to pass in |
| 38 // the function pointer. |
| 39 // Please note that TrapFnc is executed from signal context and must be |
| 40 // async-signal safe: |
| 41 // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html |
| 42 typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux); |
| 43 |
| 44 enum ArgType { |
| 45 TP_32BIT, TP_64BIT, |
| 46 }; |
| 47 |
| 48 enum Operation { |
| 49 OP_EQUAL, OP_GREATER, OP_GREATER_EQUAL, OP_HAS_BITS, |
| 50 OP_NUM_OPS, |
| 51 }; |
| 52 |
| 53 // We allow the default constructor, as it makes the ErrorCode class |
| 54 // much easier to use. But if we ever encounter an invalid ErrorCode |
| 55 // when compiling a BPF filter, we deliberately generate an invalid |
| 56 // program that will get flagged both by our Verifier class and by |
| 57 // the Linux kernel. |
| 58 ErrorCode() : |
| 59 error_type_(ET_INVALID), |
| 60 err_(SECCOMP_RET_INVALID) { |
| 61 } |
| 62 explicit ErrorCode(int err); |
| 63 |
| 64 // For all practical purposes, ErrorCodes are treated as if they were |
| 65 // structs. The copy constructor and assignment operator are trivial and |
| 66 // we do not need to explicitly specify them. |
| 67 // Most notably, it is in fact perfectly OK to directly copy the passed_ and |
| 68 // failed_ field. They only ever get set by our private constructor, and the |
| 69 // callers handle life-cycle management for these objects. |
| 70 |
| 71 // Destructor |
| 72 ~ErrorCode() { } |
| 73 |
| 74 bool Equals(const ErrorCode& err) const; |
| 75 bool LessThan(const ErrorCode& err) const; |
| 76 |
| 77 uint32_t err() const { return err_; } |
| 78 |
| 79 struct LessThan { |
| 80 bool operator()(const ErrorCode& a, const ErrorCode& b) const { |
| 81 return a.LessThan(b); |
| 82 } |
| 83 }; |
| 84 |
| 85 private: |
| 86 friend class Sandbox; |
| 87 friend class Verifier; |
| 88 |
| 89 enum ErrorType { |
| 90 ET_INVALID, ET_SIMPLE, ET_TRAP, ET_COND, |
| 91 }; |
| 92 |
| 93 // If we are wrapping a callback, we must assign a unique id. This id is |
| 94 // how the kernel tells us which one of our different SECCOMP_RET_TRAP |
| 95 // cases has been triggered. |
| 96 ErrorCode(TrapFnc fnc, const void *aux, uint16_t id); |
| 97 |
| 98 // Some system calls require inspection of arguments. This constructor |
| 99 // allows us to specify additional constraints. |
| 100 ErrorCode(int argno, ArgType width, Operation op, uint64_t value, |
| 101 const ErrorCode *passed, const ErrorCode *failed); |
| 102 |
| 103 ErrorType error_type_; |
| 104 |
| 105 union { |
| 106 // Fields needed for SECCOMP_RET_TRAP callbacks |
| 107 struct { |
| 108 TrapFnc fnc_; // Callback function and arg, if trap was |
| 109 void *aux_; // triggered by the kernel's BPF filter. |
| 110 }; |
| 111 |
| 112 // Fields needed when inspecting additional arguments. |
| 113 struct { |
| 114 uint64_t value_; // Value that we are comparing with. |
| 115 int argno_; // Syscall arg number that we are inspecting. |
| 116 ArgType width_; // Whether we are looking at a 32/64bit value. |
| 117 Operation op_; // Comparison operation. |
| 118 const ErrorCode *passed_; // Value to be returned if comparison passed, |
| 119 const ErrorCode *failed_; // or if it failed. |
| 120 }; |
| 121 }; |
| 122 |
| 123 // 32bit field used for all possible types of ErrorCode values. This is |
| 124 // the value that uniquely identifies any ErrorCode and it (typically) can |
| 125 // be emitted directly into a BPF filter program. |
| 126 uint32_t err_; |
| 127 |
| 128 }; |
| 129 |
| 130 } // namespace |
| 131 |
| 132 #endif // SANDBOX_LINUX_SECCOMP_BPF_ERRORCODE_H__ |
| OLD | NEW |