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 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" | 5 #include "sandbox/linux/bpf_dsl/bpf_dsl.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 | 8 |
| 9 #include <limits> |
| 10 |
9 #include "base/logging.h" | 11 #include "base/logging.h" |
10 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
11 #include "sandbox/linux/seccomp-bpf/errorcode.h" | 13 #include "sandbox/linux/seccomp-bpf/errorcode.h" |
12 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 14 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
13 | 15 |
14 using namespace sandbox::bpf_dsl::internal; | |
15 typedef ::sandbox::Trap::TrapFnc TrapFnc; | |
16 | |
17 namespace sandbox { | 16 namespace sandbox { |
18 namespace bpf_dsl { | 17 namespace bpf_dsl { |
19 namespace { | 18 namespace { |
20 | 19 |
21 class AllowResultExprImpl : public ResultExprImpl { | 20 class AllowResultExprImpl : public internal::ResultExprImpl { |
22 public: | 21 public: |
23 AllowResultExprImpl() {} | 22 AllowResultExprImpl() {} |
| 23 |
24 virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { | 24 virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { |
25 return ErrorCode(ErrorCode::ERR_ALLOWED); | 25 return ErrorCode(ErrorCode::ERR_ALLOWED); |
26 } | 26 } |
27 | 27 |
28 private: | 28 private: |
29 virtual ~AllowResultExprImpl() {} | 29 virtual ~AllowResultExprImpl() {} |
| 30 |
30 DISALLOW_COPY_AND_ASSIGN(AllowResultExprImpl); | 31 DISALLOW_COPY_AND_ASSIGN(AllowResultExprImpl); |
31 }; | 32 }; |
32 | 33 |
33 class ErrorResultExprImpl : public ResultExprImpl { | 34 class ErrorResultExprImpl : public internal::ResultExprImpl { |
34 public: | 35 public: |
35 explicit ErrorResultExprImpl(int err) : err_(err) { | 36 explicit ErrorResultExprImpl(int err) : err_(err) { |
36 CHECK(err_ >= ErrorCode::ERR_MIN_ERRNO && err_ <= ErrorCode::ERR_MAX_ERRNO); | 37 CHECK(err_ >= ErrorCode::ERR_MIN_ERRNO && err_ <= ErrorCode::ERR_MAX_ERRNO); |
37 } | 38 } |
| 39 |
38 virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { | 40 virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { |
39 return ErrorCode(err_); | 41 return ErrorCode(err_); |
40 } | 42 } |
41 | 43 |
42 private: | 44 private: |
43 virtual ~ErrorResultExprImpl() {} | 45 virtual ~ErrorResultExprImpl() {} |
| 46 |
44 int err_; | 47 int err_; |
| 48 |
45 DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl); | 49 DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl); |
46 }; | 50 }; |
47 | 51 |
48 class TrapResultExprImpl : public ResultExprImpl { | 52 class TrapResultExprImpl : public internal::ResultExprImpl { |
49 public: | 53 public: |
50 TrapResultExprImpl(TrapFnc func, void* arg) : func_(func), arg_(arg) { | 54 TrapResultExprImpl(Trap::TrapFnc func, void* arg) : func_(func), arg_(arg) { |
51 DCHECK(func_); | 55 DCHECK(func_); |
52 } | 56 } |
| 57 |
53 virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { | 58 virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { |
54 return sb->Trap(func_, arg_); | 59 return sb->Trap(func_, arg_); |
55 } | 60 } |
56 | 61 |
57 private: | 62 private: |
58 virtual ~TrapResultExprImpl() {} | 63 virtual ~TrapResultExprImpl() {} |
59 TrapFnc func_; | 64 |
| 65 Trap::TrapFnc func_; |
60 void* arg_; | 66 void* arg_; |
| 67 |
61 DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl); | 68 DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl); |
62 }; | 69 }; |
63 | 70 |
64 class IfThenResultExprImpl : public ResultExprImpl { | 71 class IfThenResultExprImpl : public internal::ResultExprImpl { |
65 public: | 72 public: |
66 IfThenResultExprImpl(BoolExpr cond, | 73 IfThenResultExprImpl(const BoolExpr& cond, |
67 ResultExpr then_result, | 74 const ResultExpr& then_result, |
68 ResultExpr else_result) | 75 const ResultExpr& else_result) |
69 : cond_(cond), then_result_(then_result), else_result_(else_result) {} | 76 : cond_(cond), then_result_(then_result), else_result_(else_result) {} |
| 77 |
70 virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { | 78 virtual ErrorCode Compile(SandboxBPF* sb) const OVERRIDE { |
71 return cond_->Compile( | 79 return cond_->Compile( |
72 sb, then_result_->Compile(sb), else_result_->Compile(sb)); | 80 sb, then_result_->Compile(sb), else_result_->Compile(sb)); |
73 } | 81 } |
74 | 82 |
75 private: | 83 private: |
76 virtual ~IfThenResultExprImpl() {} | 84 virtual ~IfThenResultExprImpl() {} |
| 85 |
77 BoolExpr cond_; | 86 BoolExpr cond_; |
78 ResultExpr then_result_; | 87 ResultExpr then_result_; |
79 ResultExpr else_result_; | 88 ResultExpr else_result_; |
| 89 |
80 DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl); | 90 DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl); |
81 }; | 91 }; |
82 | 92 |
83 class PrimitiveBoolExprImpl : public BoolExprImpl { | 93 class PrimitiveBoolExprImpl : public internal::BoolExprImpl { |
84 public: | 94 public: |
85 PrimitiveBoolExprImpl(int argno, | 95 PrimitiveBoolExprImpl(int argno, |
86 ErrorCode::ArgType is_32bit, | 96 ErrorCode::ArgType is_32bit, |
87 ErrorCode::Operation op, | 97 ErrorCode::Operation op, |
88 uint64_t value) | 98 uint64_t value) |
89 : argno_(argno), is_32bit_(is_32bit), op_(op), value_(value) {} | 99 : argno_(argno), is_32bit_(is_32bit), op_(op), value_(value) {} |
| 100 |
90 virtual ErrorCode Compile(SandboxBPF* sb, | 101 virtual ErrorCode Compile(SandboxBPF* sb, |
91 ErrorCode true_ec, | 102 ErrorCode true_ec, |
92 ErrorCode false_ec) const OVERRIDE { | 103 ErrorCode false_ec) const OVERRIDE { |
93 return sb->Cond(argno_, is_32bit_, op_, value_, true_ec, false_ec); | 104 return sb->Cond(argno_, is_32bit_, op_, value_, true_ec, false_ec); |
94 } | 105 } |
95 | 106 |
96 private: | 107 private: |
97 virtual ~PrimitiveBoolExprImpl() {} | 108 virtual ~PrimitiveBoolExprImpl() {} |
| 109 |
98 int argno_; | 110 int argno_; |
99 ErrorCode::ArgType is_32bit_; | 111 ErrorCode::ArgType is_32bit_; |
100 ErrorCode::Operation op_; | 112 ErrorCode::Operation op_; |
101 uint64_t value_; | 113 uint64_t value_; |
| 114 |
102 DISALLOW_COPY_AND_ASSIGN(PrimitiveBoolExprImpl); | 115 DISALLOW_COPY_AND_ASSIGN(PrimitiveBoolExprImpl); |
103 }; | 116 }; |
104 | 117 |
105 class NegateBoolExprImpl : public BoolExprImpl { | 118 class NegateBoolExprImpl : public internal::BoolExprImpl { |
106 public: | 119 public: |
107 explicit NegateBoolExprImpl(BoolExpr cond) : cond_(cond) {} | 120 explicit NegateBoolExprImpl(const BoolExpr& cond) : cond_(cond) {} |
| 121 |
108 virtual ErrorCode Compile(SandboxBPF* sb, | 122 virtual ErrorCode Compile(SandboxBPF* sb, |
109 ErrorCode true_ec, | 123 ErrorCode true_ec, |
110 ErrorCode false_ec) const OVERRIDE { | 124 ErrorCode false_ec) const OVERRIDE { |
111 return cond_->Compile(sb, false_ec, true_ec); | 125 return cond_->Compile(sb, false_ec, true_ec); |
112 } | 126 } |
113 | 127 |
114 private: | 128 private: |
115 virtual ~NegateBoolExprImpl() {} | 129 virtual ~NegateBoolExprImpl() {} |
| 130 |
116 BoolExpr cond_; | 131 BoolExpr cond_; |
| 132 |
117 DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl); | 133 DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl); |
118 }; | 134 }; |
119 | 135 |
120 class AndBoolExprImpl : public BoolExprImpl { | 136 class AndBoolExprImpl : public internal::BoolExprImpl { |
121 public: | 137 public: |
122 AndBoolExprImpl(BoolExpr lhs, BoolExpr rhs) : lhs_(lhs), rhs_(rhs) {} | 138 AndBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs) |
| 139 : lhs_(lhs), rhs_(rhs) {} |
| 140 |
123 virtual ErrorCode Compile(SandboxBPF* sb, | 141 virtual ErrorCode Compile(SandboxBPF* sb, |
124 ErrorCode true_ec, | 142 ErrorCode true_ec, |
125 ErrorCode false_ec) const OVERRIDE { | 143 ErrorCode false_ec) const OVERRIDE { |
126 return lhs_->Compile(sb, rhs_->Compile(sb, true_ec, false_ec), false_ec); | 144 return lhs_->Compile(sb, rhs_->Compile(sb, true_ec, false_ec), false_ec); |
127 } | 145 } |
128 | 146 |
129 private: | 147 private: |
130 virtual ~AndBoolExprImpl() {} | 148 virtual ~AndBoolExprImpl() {} |
131 BoolExpr lhs_, rhs_; | 149 |
| 150 BoolExpr lhs_; |
| 151 BoolExpr rhs_; |
| 152 |
132 DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl); | 153 DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl); |
133 }; | 154 }; |
134 | 155 |
135 class OrBoolExprImpl : public BoolExprImpl { | 156 class OrBoolExprImpl : public internal::BoolExprImpl { |
136 public: | 157 public: |
137 OrBoolExprImpl(BoolExpr lhs, BoolExpr rhs) : lhs_(lhs), rhs_(rhs) {} | 158 OrBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs) |
| 159 : lhs_(lhs), rhs_(rhs) {} |
| 160 |
138 virtual ErrorCode Compile(SandboxBPF* sb, | 161 virtual ErrorCode Compile(SandboxBPF* sb, |
139 ErrorCode true_ec, | 162 ErrorCode true_ec, |
140 ErrorCode false_ec) const OVERRIDE { | 163 ErrorCode false_ec) const OVERRIDE { |
141 return lhs_->Compile(sb, true_ec, rhs_->Compile(sb, true_ec, false_ec)); | 164 return lhs_->Compile(sb, true_ec, rhs_->Compile(sb, true_ec, false_ec)); |
142 } | 165 } |
143 | 166 |
144 private: | 167 private: |
145 virtual ~OrBoolExprImpl() {} | 168 virtual ~OrBoolExprImpl() {} |
146 BoolExpr lhs_, rhs_; | 169 |
| 170 BoolExpr lhs_; |
| 171 BoolExpr rhs_; |
| 172 |
147 DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl); | 173 DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl); |
148 }; | 174 }; |
149 | 175 |
150 } // namespace | 176 } // namespace |
151 | 177 |
152 namespace internal { | 178 namespace internal { |
153 | 179 |
154 BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) { | 180 BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) { |
155 CHECK(num >= 0 && num < 6); | 181 CHECK(num >= 0 && num < 6); |
156 CHECK(size >= 1 && size <= 8); | 182 CHECK(size >= 1 && size <= 8); |
157 CHECK_NE(0U, mask) << "zero mask doesn't make sense"; | 183 CHECK_NE(0U, mask) << "zero mask doesn't make sense"; |
158 CHECK_EQ(val, val & mask) << "val contains masked out bits"; | 184 CHECK_EQ(val, val & mask) << "val contains masked out bits"; |
159 | 185 |
160 // TODO(mdempsky): Should we just always use TP_64BIT? | 186 // TODO(mdempsky): Should we just always use TP_64BIT? |
161 const ErrorCode::ArgType arg_type = | 187 const ErrorCode::ArgType arg_type = |
162 (size <= 4) ? ErrorCode::TP_32BIT : ErrorCode::TP_64BIT; | 188 (size <= 4) ? ErrorCode::TP_32BIT : ErrorCode::TP_64BIT; |
163 | 189 |
164 if (mask == static_cast<uint64_t>(-1)) { | 190 if (mask == std::numeric_limits<uint64_t>::max()) { |
165 // Arg == Val | 191 // Arg == Val |
166 return BoolExpr(new const PrimitiveBoolExprImpl( | 192 return BoolExpr(new const PrimitiveBoolExprImpl( |
167 num, arg_type, ErrorCode::OP_EQUAL, val)); | 193 num, arg_type, ErrorCode::OP_EQUAL, val)); |
168 } else if (mask == val) { | 194 } |
| 195 |
| 196 if (mask == val) { |
169 // (Arg & Mask) == Mask | 197 // (Arg & Mask) == Mask |
170 return BoolExpr(new const PrimitiveBoolExprImpl( | 198 return BoolExpr(new const PrimitiveBoolExprImpl( |
171 num, arg_type, ErrorCode::OP_HAS_ALL_BITS, mask)); | 199 num, arg_type, ErrorCode::OP_HAS_ALL_BITS, mask)); |
172 } else if (val == 0) { | 200 } |
| 201 |
| 202 if (val == 0) { |
173 // (Arg & Mask) == 0, which is semantically equivalent to !((arg & mask) != | 203 // (Arg & Mask) == 0, which is semantically equivalent to !((arg & mask) != |
174 // 0). | 204 // 0). |
175 return !BoolExpr(new const PrimitiveBoolExprImpl( | 205 return !BoolExpr(new const PrimitiveBoolExprImpl( |
176 num, arg_type, ErrorCode::OP_HAS_ANY_BITS, mask)); | 206 num, arg_type, ErrorCode::OP_HAS_ANY_BITS, mask)); |
177 } else { | |
178 CHECK(false) << "Unimplemented ArgEq case"; | |
179 return BoolExpr(); | |
180 } | 207 } |
| 208 |
| 209 CHECK(false) << "Unimplemented ArgEq case"; |
| 210 return BoolExpr(); |
181 } | 211 } |
182 | 212 |
183 } // namespace internal | 213 } // namespace internal |
184 | 214 |
185 ResultExpr Allow() { | 215 ResultExpr Allow() { |
186 return ResultExpr(new const AllowResultExprImpl()); | 216 return ResultExpr(new const AllowResultExprImpl()); |
187 } | 217 } |
188 | 218 |
189 ResultExpr Error(int err) { | 219 ResultExpr Error(int err) { |
190 return ResultExpr(new const ErrorResultExprImpl(err)); | 220 return ResultExpr(new const ErrorResultExprImpl(err)); |
191 } | 221 } |
192 | 222 |
193 ResultExpr Trap(TrapFnc trap_func, void* aux) { | 223 ResultExpr Trap(Trap::TrapFnc trap_func, void* aux) { |
194 return ResultExpr(new const TrapResultExprImpl(trap_func, aux)); | 224 return ResultExpr(new const TrapResultExprImpl(trap_func, aux)); |
195 } | 225 } |
196 | 226 |
197 BoolExpr operator!(BoolExpr cond) { | 227 BoolExpr operator!(const BoolExpr& cond) { |
198 return BoolExpr(new const NegateBoolExprImpl(cond)); | 228 return BoolExpr(new const NegateBoolExprImpl(cond)); |
199 } | 229 } |
200 | 230 |
201 BoolExpr operator&&(BoolExpr lhs, BoolExpr rhs) { | 231 BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs) { |
202 return BoolExpr(new const AndBoolExprImpl(lhs, rhs)); | 232 return BoolExpr(new const AndBoolExprImpl(lhs, rhs)); |
203 } | 233 } |
204 | 234 |
205 BoolExpr operator||(BoolExpr lhs, BoolExpr rhs) { | 235 BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs) { |
206 return BoolExpr(new const OrBoolExprImpl(lhs, rhs)); | 236 return BoolExpr(new const OrBoolExprImpl(lhs, rhs)); |
207 } | 237 } |
208 | 238 |
209 Elser If(BoolExpr cond, ResultExpr then_result) { | 239 Elser If(const BoolExpr& cond, const ResultExpr& then_result) { |
210 return Elser(Cons<Elser::Clause>::List()).ElseIf(cond, then_result); | 240 return Elser(Cons<Elser::Clause>::List()).ElseIf(cond, then_result); |
211 } | 241 } |
212 | 242 |
213 Elser::Elser(Cons<Clause>::List clause_list) : clause_list_(clause_list) { | 243 Elser::Elser(Cons<Clause>::List clause_list) : clause_list_(clause_list) { |
214 } | 244 } |
215 | 245 |
216 Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) { | 246 Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) { |
217 } | 247 } |
218 | 248 |
219 Elser::~Elser() { | 249 Elser::~Elser() { |
220 } | 250 } |
221 | 251 |
222 Elser Elser::ElseIf(BoolExpr cond, ResultExpr then_result) const { | 252 Elser Elser::ElseIf(const BoolExpr& cond, const ResultExpr& then_result) const { |
223 return Elser( | 253 return Elser( |
224 Cons<Clause>::Make(std::make_pair(cond, then_result), clause_list_)); | 254 Cons<Clause>::Make(std::make_pair(cond, then_result), clause_list_)); |
225 } | 255 } |
226 | 256 |
227 ResultExpr Elser::Else(ResultExpr else_result) const { | 257 ResultExpr Elser::Else(const ResultExpr& else_result) const { |
228 // We finally have the default result expression for this | 258 // We finally have the default result expression for this |
229 // if/then/else sequence. Also, we've already accumulated all | 259 // if/then/else sequence. Also, we've already accumulated all |
230 // if/then pairs into a list of reverse order (i.e., lower priority | 260 // if/then pairs into a list of reverse order (i.e., lower priority |
231 // conditions are listed before higher priority ones). E.g., an | 261 // conditions are listed before higher priority ones). E.g., an |
232 // expression like | 262 // expression like |
233 // | 263 // |
234 // If(b1, e1).ElseIf(b2, e2).ElseIf(b3, e3).Else(e4) | 264 // If(b1, e1).ElseIf(b2, e2).ElseIf(b3, e3).Else(e4) |
235 // | 265 // |
236 // will have built up a list like | 266 // will have built up a list like |
237 // | 267 // |
(...skipping 24 matching lines...) Expand all Loading... |
262 | 292 |
263 ErrorCode SandboxBPFDSLPolicy::EvaluateSyscall(SandboxBPF* sb, | 293 ErrorCode SandboxBPFDSLPolicy::EvaluateSyscall(SandboxBPF* sb, |
264 int sysno) const { | 294 int sysno) const { |
265 return EvaluateSyscall(sysno)->Compile(sb); | 295 return EvaluateSyscall(sysno)->Compile(sb); |
266 } | 296 } |
267 | 297 |
268 ErrorCode SandboxBPFDSLPolicy::InvalidSyscall(SandboxBPF* sb) const { | 298 ErrorCode SandboxBPFDSLPolicy::InvalidSyscall(SandboxBPF* sb) const { |
269 return InvalidSyscall()->Compile(sb); | 299 return InvalidSyscall()->Compile(sb); |
270 } | 300 } |
271 | 301 |
272 ResultExpr SandboxBPFDSLPolicy::Trap(::sandbox::Trap::TrapFnc trap_func, | 302 ResultExpr SandboxBPFDSLPolicy::Trap(Trap::TrapFnc trap_func, void* aux) { |
273 void* aux) { | |
274 return bpf_dsl::Trap(trap_func, aux); | 303 return bpf_dsl::Trap(trap_func, aux); |
275 } | 304 } |
276 | 305 |
277 } // namespace bpf_dsl | 306 } // namespace bpf_dsl |
278 } // namespace sandbox | 307 } // namespace sandbox |
OLD | NEW |