| 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_BPF_DSL_POLICY_COMPILER_H_ | 5 #ifndef SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_ |
| 6 #define SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_ | 6 #define SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| 11 #include <set> | 11 #include <set> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "sandbox/linux/seccomp-bpf/codegen.h" | 16 #include "sandbox/linux/seccomp-bpf/codegen.h" |
| 17 #include "sandbox/linux/seccomp-bpf/errorcode.h" | 17 #include "sandbox/linux/seccomp-bpf/errorcode.h" |
| 18 #include "sandbox/sandbox_export.h" | 18 #include "sandbox/sandbox_export.h" |
| 19 | 19 |
| 20 namespace sandbox { | 20 namespace sandbox { |
| 21 struct Instruction; | |
| 22 | |
| 23 namespace bpf_dsl { | 21 namespace bpf_dsl { |
| 24 class Policy; | 22 class Policy; |
| 25 | 23 |
| 26 // PolicyCompiler implements the bpf_dsl compiler, allowing users to | 24 // PolicyCompiler implements the bpf_dsl compiler, allowing users to |
| 27 // transform bpf_dsl policies into BPF programs to be executed by the | 25 // transform bpf_dsl policies into BPF programs to be executed by the |
| 28 // Linux kernel. | 26 // Linux kernel. |
| 29 class SANDBOX_EXPORT PolicyCompiler { | 27 class SANDBOX_EXPORT PolicyCompiler { |
| 30 public: | 28 public: |
| 31 PolicyCompiler(const Policy* policy, TrapRegistry* registry); | 29 PolicyCompiler(const Policy* policy, TrapRegistry* registry); |
| 32 ~PolicyCompiler(); | 30 ~PolicyCompiler(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 typedef std::set<ErrorCode, struct ErrorCode::LessThan> Conds; | 92 typedef std::set<ErrorCode, struct ErrorCode::LessThan> Conds; |
| 95 | 93 |
| 96 // Used by CondExpressionHalf to track which half of the argument it's | 94 // Used by CondExpressionHalf to track which half of the argument it's |
| 97 // emitting instructions for. | 95 // emitting instructions for. |
| 98 enum ArgHalf { | 96 enum ArgHalf { |
| 99 LowerHalf, | 97 LowerHalf, |
| 100 UpperHalf, | 98 UpperHalf, |
| 101 }; | 99 }; |
| 102 | 100 |
| 103 // Compile the configured policy into a complete instruction sequence. | 101 // Compile the configured policy into a complete instruction sequence. |
| 104 Instruction* AssemblePolicy(); | 102 CodeGen::Node AssemblePolicy(); |
| 105 | 103 |
| 106 // Return an instruction sequence that checks the | 104 // Return an instruction sequence that checks the |
| 107 // arch_seccomp_data's "arch" field is valid, and then passes | 105 // arch_seccomp_data's "arch" field is valid, and then passes |
| 108 // control to |passed| if so. | 106 // control to |passed| if so. |
| 109 Instruction* CheckArch(Instruction* passed); | 107 CodeGen::Node CheckArch(CodeGen::Node passed); |
| 110 | 108 |
| 111 // If |has_unsafe_traps_| is true, returns an instruction sequence | 109 // If |has_unsafe_traps_| is true, returns an instruction sequence |
| 112 // that allows all system calls from Syscall::Call(), and otherwise | 110 // that allows all system calls from Syscall::Call(), and otherwise |
| 113 // passes control to |rest|. Otherwise, simply returns |rest|. | 111 // passes control to |rest|. Otherwise, simply returns |rest|. |
| 114 Instruction* MaybeAddEscapeHatch(Instruction* rest); | 112 CodeGen::Node MaybeAddEscapeHatch(CodeGen::Node rest); |
| 115 | 113 |
| 116 // Return an instruction sequence that loads and checks the system | 114 // Return an instruction sequence that loads and checks the system |
| 117 // call number, performs a binary search, and then dispatches to an | 115 // call number, performs a binary search, and then dispatches to an |
| 118 // appropriate instruction sequence compiled from the current | 116 // appropriate instruction sequence compiled from the current |
| 119 // policy. | 117 // policy. |
| 120 Instruction* DispatchSyscall(); | 118 CodeGen::Node DispatchSyscall(); |
| 121 | 119 |
| 122 // Return an instruction sequence that checks the system call number | 120 // Return an instruction sequence that checks the system call number |
| 123 // (expected to be loaded in register A) and if valid, passes | 121 // (expected to be loaded in register A) and if valid, passes |
| 124 // control to |passed| (with register A still valid). | 122 // control to |passed| (with register A still valid). |
| 125 Instruction* CheckSyscallNumber(Instruction* passed); | 123 CodeGen::Node CheckSyscallNumber(CodeGen::Node passed); |
| 126 | 124 |
| 127 // Finds all the ranges of system calls that need to be handled. Ranges are | 125 // Finds all the ranges of system calls that need to be handled. Ranges are |
| 128 // sorted in ascending order of system call numbers. There are no gaps in the | 126 // sorted in ascending order of system call numbers. There are no gaps in the |
| 129 // ranges. System calls with identical ErrorCodes are coalesced into a single | 127 // ranges. System calls with identical ErrorCodes are coalesced into a single |
| 130 // range. | 128 // range. |
| 131 void FindRanges(Ranges* ranges); | 129 void FindRanges(Ranges* ranges); |
| 132 | 130 |
| 133 // Returns a BPF program snippet that implements a jump table for the | 131 // Returns a BPF program snippet that implements a jump table for the |
| 134 // given range of system call numbers. This function runs recursively. | 132 // given range of system call numbers. This function runs recursively. |
| 135 Instruction* AssembleJumpTable(Ranges::const_iterator start, | 133 CodeGen::Node AssembleJumpTable(Ranges::const_iterator start, |
| 136 Ranges::const_iterator stop); | 134 Ranges::const_iterator stop); |
| 137 | 135 |
| 138 // Returns a BPF program snippet that makes the BPF filter program exit | 136 // Returns a BPF program snippet that makes the BPF filter program exit |
| 139 // with the given ErrorCode "err". N.B. the ErrorCode may very well be a | 137 // with the given ErrorCode "err". N.B. the ErrorCode may very well be a |
| 140 // conditional expression; if so, this function will recursively call | 138 // conditional expression; if so, this function will recursively call |
| 141 // CondExpression() and possibly RetExpression() to build a complex set of | 139 // CondExpression() and possibly RetExpression() to build a complex set of |
| 142 // instructions. | 140 // instructions. |
| 143 Instruction* RetExpression(const ErrorCode& err); | 141 CodeGen::Node RetExpression(const ErrorCode& err); |
| 144 | 142 |
| 145 // Returns a BPF program that evaluates the conditional expression in | 143 // Returns a BPF program that evaluates the conditional expression in |
| 146 // "cond" and returns the appropriate value from the BPF filter program. | 144 // "cond" and returns the appropriate value from the BPF filter program. |
| 147 // This function recursively calls RetExpression(); it should only ever be | 145 // This function recursively calls RetExpression(); it should only ever be |
| 148 // called from RetExpression(). | 146 // called from RetExpression(). |
| 149 Instruction* CondExpression(const ErrorCode& cond); | 147 CodeGen::Node CondExpression(const ErrorCode& cond); |
| 150 | 148 |
| 151 // Returns a BPF program that evaluates half of a conditional expression; | 149 // Returns a BPF program that evaluates half of a conditional expression; |
| 152 // it should only ever be called from CondExpression(). | 150 // it should only ever be called from CondExpression(). |
| 153 Instruction* CondExpressionHalf(const ErrorCode& cond, | 151 CodeGen::Node CondExpressionHalf(const ErrorCode& cond, |
| 154 ArgHalf half, | 152 ArgHalf half, |
| 155 Instruction* passed, | 153 CodeGen::Node passed, |
| 156 Instruction* failed); | 154 CodeGen::Node failed); |
| 157 | 155 |
| 158 // MakeTrap is the common implementation for Trap and UnsafeTrap. | 156 // MakeTrap is the common implementation for Trap and UnsafeTrap. |
| 159 ErrorCode MakeTrap(TrapRegistry::TrapFnc fnc, const void* aux, bool safe); | 157 ErrorCode MakeTrap(TrapRegistry::TrapFnc fnc, const void* aux, bool safe); |
| 160 | 158 |
| 161 const Policy* policy_; | 159 const Policy* policy_; |
| 162 TrapRegistry* registry_; | 160 TrapRegistry* registry_; |
| 163 | 161 |
| 164 Conds conds_; | 162 Conds conds_; |
| 165 CodeGen gen_; | 163 CodeGen gen_; |
| 166 bool has_unsafe_traps_; | 164 bool has_unsafe_traps_; |
| 167 | 165 |
| 168 DISALLOW_COPY_AND_ASSIGN(PolicyCompiler); | 166 DISALLOW_COPY_AND_ASSIGN(PolicyCompiler); |
| 169 }; | 167 }; |
| 170 | 168 |
| 171 } // namespace bpf_dsl | 169 } // namespace bpf_dsl |
| 172 } // namespace sandbox | 170 } // namespace sandbox |
| 173 | 171 |
| 174 #endif // SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_ | 172 #endif // SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_ |
| OLD | NEW |