| 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_ERRORCODE_H__ | 5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_ERRORCODE_H__ |
| 6 #define SANDBOX_LINUX_SECCOMP_BPF_ERRORCODE_H__ | 6 #define SANDBOX_LINUX_SECCOMP_BPF_ERRORCODE_H__ |
| 7 | 7 |
| 8 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" | 8 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" |
| 9 #include "sandbox/linux/seccomp-bpf/trap.h" | 9 #include "sandbox/linux/seccomp-bpf/trap.h" |
| 10 | 10 |
| 11 namespace playground2 { | 11 namespace playground2 { |
| 12 | 12 |
| 13 struct arch_seccomp_data; | 13 struct arch_seccomp_data; |
| 14 | 14 |
| 15 // This class holds all the possible values that can be returned by a sandbox | 15 // This class holds all the possible values that can be returned by a sandbox |
| 16 // policy. | 16 // policy. |
| 17 // We can either wrap a symbolic ErrorCode (i.e. ERR_XXX enum values), an | 17 // We can either wrap a symbolic ErrorCode (i.e. ERR_XXX enum values), an |
| 18 // errno value (in the range 0..4095), a pointer to a TrapFnc callback | 18 // errno value (in the range 0..4095), a pointer to a TrapFnc callback |
| 19 // handling a SECCOMP_RET_TRAP trap, or a complex constraint. | 19 // handling a SECCOMP_RET_TRAP trap, or a complex constraint. |
| 20 // All of the commonly used values are stored in the "err_" field. So, code | 20 // All of the commonly used values are stored in the "err_" field. So, code |
| 21 // that is using the ErrorCode class typically operates on a single 32bit | 21 // that is using the ErrorCode class typically operates on a single 32bit |
| 22 // field. | 22 // field. |
| 23 class ErrorCode { | 23 class ErrorCode { |
| 24 public: | 24 public: |
| 25 enum { | 25 enum { |
| 26 // Allow this system call. The value of ERR_ALLOWED is pretty much | 26 // Allow this system call. The value of ERR_ALLOWED is pretty much |
| 27 // completely arbitrary. But we want to pick it so that is is unlikely | 27 // completely arbitrary. But we want to pick it so that is is unlikely |
| 28 // to be passed in accidentally, when the user intended to return an | 28 // to be passed in accidentally, when the user intended to return an |
| 29 // "errno" (see below) value instead. | 29 // "errno" (see below) value instead. |
| 30 ERR_ALLOWED = 0x04000000, | 30 ERR_ALLOWED = 0x04000000, |
| 31 | 31 |
| 32 // Deny the system call with a particular "errno" value. | 32 // Deny the system call with a particular "errno" value. |
| 33 // N.B.: It is also possible to return "0" here. That would normally | 33 // N.B.: It is also possible to return "0" here. That would normally |
| 34 // indicate success, but it won't actually run the system call. | 34 // indicate success, but it won't actually run the system call. |
| 35 // This is very different from return ERR_ALLOWED. | 35 // This is very different from return ERR_ALLOWED. |
| 36 ERR_MIN_ERRNO = 0, | 36 ERR_MIN_ERRNO = 0, |
| 37 // TODO(markus): Android only supports errno up to 255 | 37 // TODO(markus): Android only supports errno up to 255 |
| 38 // (crbug.com/181647). | 38 // (crbug.com/181647). |
| 39 ERR_MAX_ERRNO = 4095, | 39 ERR_MAX_ERRNO = 4095, |
| 40 }; | 40 }; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 enum Operation { | 78 enum Operation { |
| 79 // Test whether the system call argument is equal to the operand. | 79 // Test whether the system call argument is equal to the operand. |
| 80 OP_EQUAL, | 80 OP_EQUAL, |
| 81 | 81 |
| 82 // Test whether the system call argument is greater (or equal) to the | 82 // Test whether the system call argument is greater (or equal) to the |
| 83 // operand. Please note that all tests always operate on unsigned | 83 // operand. Please note that all tests always operate on unsigned |
| 84 // values. You can generally emulate signed tests, if that's what you | 84 // values. You can generally emulate signed tests, if that's what you |
| 85 // need. | 85 // need. |
| 86 // TODO(markus): Check whether we should automatically emulate signed | 86 // TODO(markus): Check whether we should automatically emulate signed |
| 87 // operations. | 87 // operations. |
| 88 OP_GREATER_UNSIGNED, OP_GREATER_EQUAL_UNSIGNED, | 88 OP_GREATER_UNSIGNED, |
| 89 OP_GREATER_EQUAL_UNSIGNED, |
| 89 | 90 |
| 90 // Tests a system call argument against a bit mask. | 91 // Tests a system call argument against a bit mask. |
| 91 // The "ALL_BITS" variant performs this test: "arg & mask == mask" | 92 // The "ALL_BITS" variant performs this test: "arg & mask == mask" |
| 92 // This implies that a mask of zero always results in a passing test. | 93 // This implies that a mask of zero always results in a passing test. |
| 93 // The "ANY_BITS" variant performs this test: "arg & mask != 0" | 94 // The "ANY_BITS" variant performs this test: "arg & mask != 0" |
| 94 // This implies that a mask of zero always results in a failing test. | 95 // This implies that a mask of zero always results in a failing test. |
| 95 OP_HAS_ALL_BITS, OP_HAS_ANY_BITS, | 96 OP_HAS_ALL_BITS, |
| 97 OP_HAS_ANY_BITS, |
| 96 | 98 |
| 97 // Total number of operations. | 99 // Total number of operations. |
| 98 OP_NUM_OPS, | 100 OP_NUM_OPS, |
| 99 }; | 101 }; |
| 100 | 102 |
| 101 enum ErrorType { | 103 enum ErrorType { |
| 102 ET_INVALID, ET_SIMPLE, ET_TRAP, ET_COND, | 104 ET_INVALID, |
| 105 ET_SIMPLE, |
| 106 ET_TRAP, |
| 107 ET_COND, |
| 103 }; | 108 }; |
| 104 | 109 |
| 105 // We allow the default constructor, as it makes the ErrorCode class | 110 // We allow the default constructor, as it makes the ErrorCode class |
| 106 // much easier to use. But if we ever encounter an invalid ErrorCode | 111 // much easier to use. But if we ever encounter an invalid ErrorCode |
| 107 // when compiling a BPF filter, we deliberately generate an invalid | 112 // when compiling a BPF filter, we deliberately generate an invalid |
| 108 // program that will get flagged both by our Verifier class and by | 113 // program that will get flagged both by our Verifier class and by |
| 109 // the Linux kernel. | 114 // the Linux kernel. |
| 110 ErrorCode() : | 115 ErrorCode() : error_type_(ET_INVALID), err_(SECCOMP_RET_INVALID) {} |
| 111 error_type_(ET_INVALID), | |
| 112 err_(SECCOMP_RET_INVALID) { | |
| 113 } | |
| 114 explicit ErrorCode(int err); | 116 explicit ErrorCode(int err); |
| 115 | 117 |
| 116 // For all practical purposes, ErrorCodes are treated as if they were | 118 // For all practical purposes, ErrorCodes are treated as if they were |
| 117 // structs. The copy constructor and assignment operator are trivial and | 119 // structs. The copy constructor and assignment operator are trivial and |
| 118 // we do not need to explicitly specify them. | 120 // we do not need to explicitly specify them. |
| 119 // Most notably, it is in fact perfectly OK to directly copy the passed_ and | 121 // Most notably, it is in fact perfectly OK to directly copy the passed_ and |
| 120 // failed_ field. They only ever get set by our private constructor, and the | 122 // failed_ field. They only ever get set by our private constructor, and the |
| 121 // callers handle life-cycle management for these objects. | 123 // callers handle life-cycle management for these objects. |
| 122 | 124 |
| 123 // Destructor | 125 // Destructor |
| 124 ~ErrorCode() { } | 126 ~ErrorCode() {} |
| 125 | 127 |
| 126 bool Equals(const ErrorCode& err) const; | 128 bool Equals(const ErrorCode& err) const; |
| 127 bool LessThan(const ErrorCode& err) const; | 129 bool LessThan(const ErrorCode& err) const; |
| 128 | 130 |
| 129 uint32_t err() const { return err_; } | 131 uint32_t err() const { return err_; } |
| 130 ErrorType error_type() const { return error_type_; } | 132 ErrorType error_type() const { return error_type_; } |
| 131 | 133 |
| 132 bool safe() const { return safe_; } | 134 bool safe() const { return safe_; } |
| 133 | 135 |
| 134 uint64_t value() const { return value_; } | 136 uint64_t value() const { return value_; } |
| 135 int argno() const { return argno_; } | 137 int argno() const { return argno_; } |
| 136 ArgType width() const { return width_; } | 138 ArgType width() const { return width_; } |
| 137 Operation op() const { return op_; } | 139 Operation op() const { return op_; } |
| 138 const ErrorCode *passed() const { return passed_; } | 140 const ErrorCode* passed() const { return passed_; } |
| 139 const ErrorCode *failed() const { return failed_; } | 141 const ErrorCode* failed() const { return failed_; } |
| 140 | 142 |
| 141 struct LessThan { | 143 struct LessThan { |
| 142 bool operator()(const ErrorCode& a, const ErrorCode& b) const { | 144 bool operator()(const ErrorCode& a, const ErrorCode& b) const { |
| 143 return a.LessThan(b); | 145 return a.LessThan(b); |
| 144 } | 146 } |
| 145 }; | 147 }; |
| 146 | 148 |
| 147 private: | 149 private: |
| 148 friend class CodeGen; | 150 friend class CodeGen; |
| 149 friend class Sandbox; | 151 friend class Sandbox; |
| 150 friend class Trap; | 152 friend class Trap; |
| 151 | 153 |
| 152 // If we are wrapping a callback, we must assign a unique id. This id is | 154 // If we are wrapping a callback, we must assign a unique id. This id is |
| 153 // how the kernel tells us which one of our different SECCOMP_RET_TRAP | 155 // how the kernel tells us which one of our different SECCOMP_RET_TRAP |
| 154 // cases has been triggered. | 156 // cases has been triggered. |
| 155 ErrorCode(Trap::TrapFnc fnc, const void *aux, bool safe, uint16_t id); | 157 ErrorCode(Trap::TrapFnc fnc, const void* aux, bool safe, uint16_t id); |
| 156 | 158 |
| 157 // Some system calls require inspection of arguments. This constructor | 159 // Some system calls require inspection of arguments. This constructor |
| 158 // allows us to specify additional constraints. | 160 // allows us to specify additional constraints. |
| 159 ErrorCode(int argno, ArgType width, Operation op, uint64_t value, | 161 ErrorCode(int argno, |
| 160 const ErrorCode *passed, const ErrorCode *failed); | 162 ArgType width, |
| 163 Operation op, |
| 164 uint64_t value, |
| 165 const ErrorCode* passed, |
| 166 const ErrorCode* failed); |
| 161 | 167 |
| 162 ErrorType error_type_; | 168 ErrorType error_type_; |
| 163 | 169 |
| 164 union { | 170 union { |
| 165 // Fields needed for SECCOMP_RET_TRAP callbacks | 171 // Fields needed for SECCOMP_RET_TRAP callbacks |
| 166 struct { | 172 struct { |
| 167 Trap::TrapFnc fnc_; // Callback function and arg, if trap was | 173 Trap::TrapFnc fnc_; // Callback function and arg, if trap was |
| 168 void *aux_; // triggered by the kernel's BPF filter. | 174 void* aux_; // triggered by the kernel's BPF filter. |
| 169 bool safe_; // Keep sandbox active while calling fnc_() | 175 bool safe_; // Keep sandbox active while calling fnc_() |
| 170 }; | 176 }; |
| 171 | 177 |
| 172 // Fields needed when inspecting additional arguments. | 178 // Fields needed when inspecting additional arguments. |
| 173 struct { | 179 struct { |
| 174 uint64_t value_; // Value that we are comparing with. | 180 uint64_t value_; // Value that we are comparing with. |
| 175 int argno_; // Syscall arg number that we are inspecting. | 181 int argno_; // Syscall arg number that we are inspecting. |
| 176 ArgType width_; // Whether we are looking at a 32/64bit value. | 182 ArgType width_; // Whether we are looking at a 32/64bit value. |
| 177 Operation op_; // Comparison operation. | 183 Operation op_; // Comparison operation. |
| 178 const ErrorCode *passed_; // Value to be returned if comparison passed, | 184 const ErrorCode* passed_; // Value to be returned if comparison passed, |
| 179 const ErrorCode *failed_; // or if it failed. | 185 const ErrorCode* failed_; // or if it failed. |
| 180 }; | 186 }; |
| 181 }; | 187 }; |
| 182 | 188 |
| 183 // 32bit field used for all possible types of ErrorCode values. This is | 189 // 32bit field used for all possible types of ErrorCode values. This is |
| 184 // the value that uniquely identifies any ErrorCode and it (typically) can | 190 // the value that uniquely identifies any ErrorCode and it (typically) can |
| 185 // be emitted directly into a BPF filter program. | 191 // be emitted directly into a BPF filter program. |
| 186 uint32_t err_; | 192 uint32_t err_; |
| 187 | |
| 188 }; | 193 }; |
| 189 | 194 |
| 190 } // namespace | 195 } // namespace |
| 191 | 196 |
| 192 #endif // SANDBOX_LINUX_SECCOMP_BPF_ERRORCODE_H__ | 197 #endif // SANDBOX_LINUX_SECCOMP_BPF_ERRORCODE_H__ |
| OLD | NEW |