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 |