| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_BPF_DSL_BPF_DSL_H_ | 5 #ifndef SANDBOX_LINUX_BPF_DSL_BPF_DSL_H_ |
| 6 #define SANDBOX_LINUX_BPF_DSL_BPF_DSL_H_ | 6 #define SANDBOX_LINUX_BPF_DSL_BPF_DSL_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> |
| 11 | 12 |
| 12 #include "base/macros.h" | 13 #include "base/macros.h" |
| 13 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 14 #include "sandbox/linux/bpf_dsl/cons.h" | 15 #include "sandbox/linux/bpf_dsl/cons.h" |
| 15 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" | 16 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h" |
| 16 #include "sandbox/linux/seccomp-bpf/trap.h" | 17 #include "sandbox/linux/seccomp-bpf/trap.h" |
| 17 #include "sandbox/sandbox_export.h" | 18 #include "sandbox/sandbox_export.h" |
| 18 | 19 |
| 19 namespace sandbox { | 20 namespace sandbox { |
| 20 class ErrorCode; | 21 class ErrorCode; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 // return Allow(); | 53 // return Allow(); |
| 53 // } | 54 // } |
| 54 // } | 55 // } |
| 55 // | 56 // |
| 56 // private: | 57 // private: |
| 57 // DISALLOW_COPY_AND_ASSIGN(SillyPolicy); | 58 // DISALLOW_COPY_AND_ASSIGN(SillyPolicy); |
| 58 // }; | 59 // }; |
| 59 // | 60 // |
| 60 // More generally, the DSL currently supports the following grammar: | 61 // More generally, the DSL currently supports the following grammar: |
| 61 // | 62 // |
| 62 // result = Allow() | Error(errno) | Trap(trap_func, arg) | 63 // result = Allow() | Error(errno) | Trap(trap_func, aux) |
| 63 // | If(bool, result)[.ElseIf(bool, result)].Else(result) | 64 // | If(bool, result)[.ElseIf(bool, result)].Else(result) |
| 64 // bool = arg == val | (arg & mask) == val | 65 // | Switch(arg)[.Case(val, result)].Default(result) |
| 65 // | !bool | bool && bool | bool || bool | 66 // bool = BoolConst(boolean) | !bool | bool && bool | bool || bool |
| 67 // | arg == val |
| 68 // arg = Arg<T>(num) | arg & mask |
| 66 // | 69 // |
| 67 // The semantics of each function and operator are intended to be | 70 // The semantics of each function and operator are intended to be |
| 68 // intuitive, but are described in more detail below. | 71 // intuitive, but are described in more detail below. |
| 69 // | 72 // |
| 70 // (Credit to Sean Parent's "Inheritance is the Base Class of Evil" | 73 // (Credit to Sean Parent's "Inheritance is the Base Class of Evil" |
| 71 // talk at Going Native 2013 for promoting value semantics via shared | 74 // talk at Going Native 2013 for promoting value semantics via shared |
| 72 // pointers to immutable state.) | 75 // pointers to immutable state.) |
| 73 | 76 |
| 74 namespace sandbox { | 77 namespace sandbox { |
| 75 namespace bpf_dsl { | 78 namespace bpf_dsl { |
| 76 | 79 |
| 77 // Forward declarations of classes; see below for proper documentation. | 80 // Forward declarations of classes; see below for proper documentation. |
| 78 class Elser; | 81 class Elser; |
| 82 template <typename T> |
| 83 class Caser; |
| 79 namespace internal { | 84 namespace internal { |
| 80 class ResultExprImpl; | 85 class ResultExprImpl; |
| 81 class BoolExprImpl; | 86 class BoolExprImpl; |
| 82 } | 87 } |
| 83 | 88 |
| 84 // ResultExpr is an opaque reference to an immutable result expression tree. | 89 // ResultExpr is an opaque reference to an immutable result expression tree. |
| 85 typedef scoped_refptr<const internal::ResultExprImpl> ResultExpr; | 90 typedef scoped_refptr<const internal::ResultExprImpl> ResultExpr; |
| 86 | 91 |
| 87 // BoolExpr is an opaque reference to an immutable boolean expression tree. | 92 // BoolExpr is an opaque reference to an immutable boolean expression tree. |
| 88 typedef scoped_refptr<const internal::BoolExprImpl> BoolExpr; | 93 typedef scoped_refptr<const internal::BoolExprImpl> BoolExpr; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 Arg(int num, uint64_t mask) : num_(num), mask_(mask) {} | 157 Arg(int num, uint64_t mask) : num_(num), mask_(mask) {} |
| 153 | 158 |
| 154 BoolExpr EqualTo(T val) const; | 159 BoolExpr EqualTo(T val) const; |
| 155 | 160 |
| 156 int num_; | 161 int num_; |
| 157 uint64_t mask_; | 162 uint64_t mask_; |
| 158 | 163 |
| 159 DISALLOW_ASSIGN(Arg); | 164 DISALLOW_ASSIGN(Arg); |
| 160 }; | 165 }; |
| 161 | 166 |
| 167 // Convert a bool value into a BoolExpr. |
| 168 SANDBOX_EXPORT BoolExpr BoolConst(bool value); |
| 169 |
| 162 // Various ways to combine boolean expressions into more complex expressions. | 170 // Various ways to combine boolean expressions into more complex expressions. |
| 163 // They follow standard boolean algebra laws. | 171 // They follow standard boolean algebra laws. |
| 164 SANDBOX_EXPORT BoolExpr operator!(const BoolExpr& cond); | 172 SANDBOX_EXPORT BoolExpr operator!(const BoolExpr& cond); |
| 165 SANDBOX_EXPORT BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs); | 173 SANDBOX_EXPORT BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs); |
| 166 SANDBOX_EXPORT BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs); | 174 SANDBOX_EXPORT BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs); |
| 167 | 175 |
| 168 // If begins a conditional result expression predicated on the | 176 // If begins a conditional result expression predicated on the |
| 169 // specified boolean expression. | 177 // specified boolean expression. |
| 170 SANDBOX_EXPORT Elser If(const BoolExpr& cond, const ResultExpr& then_result); | 178 SANDBOX_EXPORT Elser If(const BoolExpr& cond, const ResultExpr& then_result); |
| 171 | 179 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 183 ResultExpr Else(const ResultExpr& else_result) const; | 191 ResultExpr Else(const ResultExpr& else_result) const; |
| 184 | 192 |
| 185 private: | 193 private: |
| 186 typedef std::pair<BoolExpr, ResultExpr> Clause; | 194 typedef std::pair<BoolExpr, ResultExpr> Clause; |
| 187 | 195 |
| 188 explicit Elser(Cons<Clause>::List clause_list); | 196 explicit Elser(Cons<Clause>::List clause_list); |
| 189 | 197 |
| 190 Cons<Clause>::List clause_list_; | 198 Cons<Clause>::List clause_list_; |
| 191 | 199 |
| 192 friend Elser If(const BoolExpr&, const ResultExpr&); | 200 friend Elser If(const BoolExpr&, const ResultExpr&); |
| 201 template <typename T> |
| 202 friend Caser<T> Switch(const Arg<T>&); |
| 193 DISALLOW_ASSIGN(Elser); | 203 DISALLOW_ASSIGN(Elser); |
| 194 }; | 204 }; |
| 195 | 205 |
| 206 // Switch begins a switch expression dispatched according to the |
| 207 // specified argument value. |
| 208 template <typename T> |
| 209 SANDBOX_EXPORT Caser<T> Switch(const Arg<T>& arg); |
| 210 |
| 211 template <typename T> |
| 212 class SANDBOX_EXPORT Caser { |
| 213 public: |
| 214 Caser(const Caser<T>& caser) : arg_(caser.arg_), elser_(caser.elser_) {} |
| 215 ~Caser() {} |
| 216 |
| 217 // Case adds a single-value "case" clause to the switch. |
| 218 Caser<T> Case(T value, ResultExpr result) const; |
| 219 |
| 220 // Cases adds a multiple-value "case" clause to the switch. |
| 221 // See also the SANDBOX_BPF_DSL_CASES macro below for a more idiomatic way |
| 222 // of using this function. |
| 223 Caser<T> Cases(const std::vector<T>& values, ResultExpr result) const; |
| 224 |
| 225 // Terminate the switch with a "default" clause. |
| 226 ResultExpr Default(ResultExpr result) const; |
| 227 |
| 228 private: |
| 229 Caser(const Arg<T>& arg, Elser elser) : arg_(arg), elser_(elser) {} |
| 230 |
| 231 Arg<T> arg_; |
| 232 Elser elser_; |
| 233 |
| 234 template <typename U> |
| 235 friend Caser<U> Switch(const Arg<U>&); |
| 236 DISALLOW_ASSIGN(Caser); |
| 237 }; |
| 238 |
| 239 // Recommended usage is to put |
| 240 // #define CASES SANDBOX_BPF_DSL_CASES |
| 241 // near the top of the .cc file (e.g., nearby any "using" statements), then |
| 242 // use like: |
| 243 // Switch(arg).CASES((3, 5, 7), result)...; |
| 244 #define SANDBOX_BPF_DSL_CASES(values, result) \ |
| 245 Cases(SANDBOX_BPF_DSL_CASES_HELPER values, result) |
| 246 |
| 247 // Helper macro to construct a std::vector from an initializer list. |
| 248 // TODO(mdempsky): Convert to use C++11 initializer lists instead. |
| 249 #define SANDBOX_BPF_DSL_CASES_HELPER(value, ...) \ |
| 250 ({ \ |
| 251 const __typeof__(value) bpf_dsl_cases_values[] = {value, __VA_ARGS__}; \ |
| 252 std::vector<__typeof__(value)>( \ |
| 253 bpf_dsl_cases_values, \ |
| 254 bpf_dsl_cases_values + arraysize(bpf_dsl_cases_values)); \ |
| 255 }) |
| 256 |
| 196 // ===================================================================== | 257 // ===================================================================== |
| 197 // Official API ends here. | 258 // Official API ends here. |
| 198 // ===================================================================== | 259 // ===================================================================== |
| 199 | 260 |
| 200 // Definitions below are necessary here only for C++03 compatibility. | 261 // Definitions below are necessary here only for C++03 compatibility. |
| 201 // Once C++11 is available, they should be moved into bpf_dsl.cc via extern | 262 // Once C++11 is available, they should be moved into bpf_dsl.cc via extern |
| 202 // templates. | 263 // templates. |
| 203 namespace internal { | 264 namespace internal { |
| 204 | 265 |
| 205 // Returns a boolean expression that represents whether system call | 266 // Returns a boolean expression that represents whether system call |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 // reading the header documentation. | 315 // reading the header documentation. |
| 255 // | 316 // |
| 256 // Additionally, we use this helper member function to avoid linker errors | 317 // Additionally, we use this helper member function to avoid linker errors |
| 257 // caused by defining operator== out-of-line. For a more detailed explanation, | 318 // caused by defining operator== out-of-line. For a more detailed explanation, |
| 258 // see http://www.parashift.com/c++-faq-lite/template-friends.html. | 319 // see http://www.parashift.com/c++-faq-lite/template-friends.html. |
| 259 template <typename T> | 320 template <typename T> |
| 260 BoolExpr Arg<T>::EqualTo(T val) const { | 321 BoolExpr Arg<T>::EqualTo(T val) const { |
| 261 return internal::ArgEq(num_, sizeof(T), mask_, static_cast<uint64_t>(val)); | 322 return internal::ArgEq(num_, sizeof(T), mask_, static_cast<uint64_t>(val)); |
| 262 } | 323 } |
| 263 | 324 |
| 325 template <typename T> |
| 326 SANDBOX_EXPORT Caser<T> Switch(const Arg<T>& arg) { |
| 327 return Caser<T>(arg, Elser(Cons<Elser::Clause>::List())); |
| 328 } |
| 329 |
| 330 template <typename T> |
| 331 Caser<T> Caser<T>::Case(T value, ResultExpr result) const { |
| 332 return SANDBOX_BPF_DSL_CASES((value), result); |
| 333 } |
| 334 |
| 335 template <typename T> |
| 336 Caser<T> Caser<T>::Cases(const std::vector<T>& values, |
| 337 ResultExpr result) const { |
| 338 // Theoretically we could evaluate arg_ just once and emit a more efficient |
| 339 // dispatch table, but for now we simply translate into an equivalent |
| 340 // If/ElseIf/Else chain. |
| 341 |
| 342 typedef typename std::vector<T>::const_iterator Iter; |
| 343 BoolExpr test = BoolConst(false); |
| 344 for (Iter i = values.begin(), end = values.end(); i != end; ++i) { |
| 345 test = test || (arg_ == *i); |
| 346 } |
| 347 return Caser<T>(arg_, elser_.ElseIf(test, result)); |
| 348 } |
| 349 |
| 350 template <typename T> |
| 351 ResultExpr Caser<T>::Default(ResultExpr result) const { |
| 352 return elser_.Else(result); |
| 353 } |
| 354 |
| 264 } // namespace bpf_dsl | 355 } // namespace bpf_dsl |
| 265 } // namespace sandbox | 356 } // namespace sandbox |
| 266 | 357 |
| 267 #endif // SANDBOX_LINUX_BPF_DSL_BPF_DSL_H_ | 358 #endif // SANDBOX_LINUX_BPF_DSL_BPF_DSL_H_ |
| OLD | NEW |