Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: sandbox/linux/bpf_dsl/bpf_dsl.cc

Issue 670183003: Update from chromium 62675d9fb31fb8cedc40f68e78e8445a74f362e7 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sandbox/linux/bpf_dsl/bpf_dsl.h ('k') | sandbox/linux/bpf_dsl/bpf_dsl_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
6
7 #include <errno.h>
8
9 #include <limits>
10
11 #include "base/logging.h"
12 #include "base/memory/ref_counted.h"
13 #include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h"
14 #include "sandbox/linux/bpf_dsl/policy_compiler.h"
15 #include "sandbox/linux/seccomp-bpf/errorcode.h"
16
17 namespace sandbox {
18 namespace bpf_dsl {
19 namespace {
20
21 class AllowResultExprImpl : public internal::ResultExprImpl {
22 public:
23 AllowResultExprImpl() {}
24
25 virtual ErrorCode Compile(PolicyCompiler* pc) const override {
26 return ErrorCode(ErrorCode::ERR_ALLOWED);
27 }
28
29 private:
30 virtual ~AllowResultExprImpl() {}
31
32 DISALLOW_COPY_AND_ASSIGN(AllowResultExprImpl);
33 };
34
35 class ErrorResultExprImpl : public internal::ResultExprImpl {
36 public:
37 explicit ErrorResultExprImpl(int err) : err_(err) {
38 CHECK(err_ >= ErrorCode::ERR_MIN_ERRNO && err_ <= ErrorCode::ERR_MAX_ERRNO);
39 }
40
41 virtual ErrorCode Compile(PolicyCompiler* pc) const override {
42 return pc->Error(err_);
43 }
44
45 private:
46 virtual ~ErrorResultExprImpl() {}
47
48 int err_;
49
50 DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl);
51 };
52
53 class KillResultExprImpl : public internal::ResultExprImpl {
54 public:
55 explicit KillResultExprImpl(const char* msg) : msg_(msg) { DCHECK(msg_); }
56
57 virtual ErrorCode Compile(PolicyCompiler* pc) const override {
58 return pc->Kill(msg_);
59 }
60
61 private:
62 virtual ~KillResultExprImpl() {}
63
64 const char* msg_;
65
66 DISALLOW_COPY_AND_ASSIGN(KillResultExprImpl);
67 };
68
69 class TraceResultExprImpl : public internal::ResultExprImpl {
70 public:
71 TraceResultExprImpl(uint16_t aux) : aux_(aux) {}
72
73 virtual ErrorCode Compile(PolicyCompiler* pc) const override {
74 return ErrorCode(ErrorCode::ERR_TRACE + aux_);
75 }
76
77 private:
78 virtual ~TraceResultExprImpl() {}
79
80 uint16_t aux_;
81
82 DISALLOW_COPY_AND_ASSIGN(TraceResultExprImpl);
83 };
84
85 class TrapResultExprImpl : public internal::ResultExprImpl {
86 public:
87 TrapResultExprImpl(TrapRegistry::TrapFnc func, const void* arg)
88 : func_(func), arg_(arg) {
89 DCHECK(func_);
90 }
91
92 virtual ErrorCode Compile(PolicyCompiler* pc) const override {
93 return pc->Trap(func_, arg_);
94 }
95
96 private:
97 virtual ~TrapResultExprImpl() {}
98
99 TrapRegistry::TrapFnc func_;
100 const void* arg_;
101
102 DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl);
103 };
104
105 class UnsafeTrapResultExprImpl : public internal::ResultExprImpl {
106 public:
107 UnsafeTrapResultExprImpl(TrapRegistry::TrapFnc func, const void* arg)
108 : func_(func), arg_(arg) {
109 DCHECK(func_);
110 }
111
112 virtual ErrorCode Compile(PolicyCompiler* pc) const override {
113 return pc->UnsafeTrap(func_, arg_);
114 }
115
116 virtual bool HasUnsafeTraps() const override { return true; }
117
118 private:
119 virtual ~UnsafeTrapResultExprImpl() {}
120
121 TrapRegistry::TrapFnc func_;
122 const void* arg_;
123
124 DISALLOW_COPY_AND_ASSIGN(UnsafeTrapResultExprImpl);
125 };
126
127 class IfThenResultExprImpl : public internal::ResultExprImpl {
128 public:
129 IfThenResultExprImpl(const BoolExpr& cond,
130 const ResultExpr& then_result,
131 const ResultExpr& else_result)
132 : cond_(cond), then_result_(then_result), else_result_(else_result) {}
133
134 virtual ErrorCode Compile(PolicyCompiler* pc) const override {
135 return cond_->Compile(
136 pc, then_result_->Compile(pc), else_result_->Compile(pc));
137 }
138
139 virtual bool HasUnsafeTraps() const override {
140 return then_result_->HasUnsafeTraps() || else_result_->HasUnsafeTraps();
141 }
142
143 private:
144 virtual ~IfThenResultExprImpl() {}
145
146 BoolExpr cond_;
147 ResultExpr then_result_;
148 ResultExpr else_result_;
149
150 DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl);
151 };
152
153 class ConstBoolExprImpl : public internal::BoolExprImpl {
154 public:
155 ConstBoolExprImpl(bool value) : value_(value) {}
156
157 virtual ErrorCode Compile(PolicyCompiler* pc,
158 ErrorCode true_ec,
159 ErrorCode false_ec) const override {
160 return value_ ? true_ec : false_ec;
161 }
162
163 private:
164 virtual ~ConstBoolExprImpl() {}
165
166 bool value_;
167
168 DISALLOW_COPY_AND_ASSIGN(ConstBoolExprImpl);
169 };
170
171 class PrimitiveBoolExprImpl : public internal::BoolExprImpl {
172 public:
173 PrimitiveBoolExprImpl(int argno,
174 ErrorCode::ArgType is_32bit,
175 uint64_t mask,
176 uint64_t value)
177 : argno_(argno), is_32bit_(is_32bit), mask_(mask), value_(value) {}
178
179 virtual ErrorCode Compile(PolicyCompiler* pc,
180 ErrorCode true_ec,
181 ErrorCode false_ec) const override {
182 return pc->CondMaskedEqual(
183 argno_, is_32bit_, mask_, value_, true_ec, false_ec);
184 }
185
186 private:
187 virtual ~PrimitiveBoolExprImpl() {}
188
189 int argno_;
190 ErrorCode::ArgType is_32bit_;
191 uint64_t mask_;
192 uint64_t value_;
193
194 DISALLOW_COPY_AND_ASSIGN(PrimitiveBoolExprImpl);
195 };
196
197 class NegateBoolExprImpl : public internal::BoolExprImpl {
198 public:
199 explicit NegateBoolExprImpl(const BoolExpr& cond) : cond_(cond) {}
200
201 virtual ErrorCode Compile(PolicyCompiler* pc,
202 ErrorCode true_ec,
203 ErrorCode false_ec) const override {
204 return cond_->Compile(pc, false_ec, true_ec);
205 }
206
207 private:
208 virtual ~NegateBoolExprImpl() {}
209
210 BoolExpr cond_;
211
212 DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl);
213 };
214
215 class AndBoolExprImpl : public internal::BoolExprImpl {
216 public:
217 AndBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
218 : lhs_(lhs), rhs_(rhs) {}
219
220 virtual ErrorCode Compile(PolicyCompiler* pc,
221 ErrorCode true_ec,
222 ErrorCode false_ec) const override {
223 return lhs_->Compile(pc, rhs_->Compile(pc, true_ec, false_ec), false_ec);
224 }
225
226 private:
227 virtual ~AndBoolExprImpl() {}
228
229 BoolExpr lhs_;
230 BoolExpr rhs_;
231
232 DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl);
233 };
234
235 class OrBoolExprImpl : public internal::BoolExprImpl {
236 public:
237 OrBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
238 : lhs_(lhs), rhs_(rhs) {}
239
240 virtual ErrorCode Compile(PolicyCompiler* pc,
241 ErrorCode true_ec,
242 ErrorCode false_ec) const override {
243 return lhs_->Compile(pc, true_ec, rhs_->Compile(pc, true_ec, false_ec));
244 }
245
246 private:
247 virtual ~OrBoolExprImpl() {}
248
249 BoolExpr lhs_;
250 BoolExpr rhs_;
251
252 DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl);
253 };
254
255 } // namespace
256
257 namespace internal {
258
259 bool ResultExprImpl::HasUnsafeTraps() const {
260 return false;
261 }
262
263 uint64_t DefaultMask(size_t size) {
264 switch (size) {
265 case 4:
266 return std::numeric_limits<uint32_t>::max();
267 case 8:
268 return std::numeric_limits<uint64_t>::max();
269 default:
270 CHECK(false) << "Unimplemented DefaultMask case";
271 return 0;
272 }
273 }
274
275 BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) {
276 CHECK(size == 4 || size == 8);
277
278 // TODO(mdempsky): Should we just always use TP_64BIT?
279 const ErrorCode::ArgType arg_type =
280 (size == 4) ? ErrorCode::TP_32BIT : ErrorCode::TP_64BIT;
281
282 return BoolExpr(new const PrimitiveBoolExprImpl(num, arg_type, mask, val));
283 }
284
285 } // namespace internal
286
287 ResultExpr Allow() {
288 return ResultExpr(new const AllowResultExprImpl());
289 }
290
291 ResultExpr Error(int err) {
292 return ResultExpr(new const ErrorResultExprImpl(err));
293 }
294
295 ResultExpr Kill(const char* msg) {
296 return ResultExpr(new const KillResultExprImpl(msg));
297 }
298
299 ResultExpr Trace(uint16_t aux) {
300 return ResultExpr(new const TraceResultExprImpl(aux));
301 }
302
303 ResultExpr Trap(TrapRegistry::TrapFnc trap_func, const void* aux) {
304 return ResultExpr(new const TrapResultExprImpl(trap_func, aux));
305 }
306
307 ResultExpr UnsafeTrap(TrapRegistry::TrapFnc trap_func, const void* aux) {
308 return ResultExpr(new const UnsafeTrapResultExprImpl(trap_func, aux));
309 }
310
311 BoolExpr BoolConst(bool value) {
312 return BoolExpr(new const ConstBoolExprImpl(value));
313 }
314
315 BoolExpr operator!(const BoolExpr& cond) {
316 return BoolExpr(new const NegateBoolExprImpl(cond));
317 }
318
319 BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs) {
320 return BoolExpr(new const AndBoolExprImpl(lhs, rhs));
321 }
322
323 BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs) {
324 return BoolExpr(new const OrBoolExprImpl(lhs, rhs));
325 }
326
327 Elser If(const BoolExpr& cond, const ResultExpr& then_result) {
328 return Elser(nullptr).ElseIf(cond, then_result);
329 }
330
331 Elser::Elser(cons::List<Clause> clause_list) : clause_list_(clause_list) {
332 }
333
334 Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) {
335 }
336
337 Elser::~Elser() {
338 }
339
340 Elser Elser::ElseIf(const BoolExpr& cond, const ResultExpr& then_result) const {
341 return Elser(Cons(std::make_pair(cond, then_result), clause_list_));
342 }
343
344 ResultExpr Elser::Else(const ResultExpr& else_result) const {
345 // We finally have the default result expression for this
346 // if/then/else sequence. Also, we've already accumulated all
347 // if/then pairs into a list of reverse order (i.e., lower priority
348 // conditions are listed before higher priority ones). E.g., an
349 // expression like
350 //
351 // If(b1, e1).ElseIf(b2, e2).ElseIf(b3, e3).Else(e4)
352 //
353 // will have built up a list like
354 //
355 // [(b3, e3), (b2, e2), (b1, e1)].
356 //
357 // Now that we have e4, we can walk the list and create a ResultExpr
358 // tree like:
359 //
360 // expr = e4
361 // expr = (b3 ? e3 : expr) = (b3 ? e3 : e4)
362 // expr = (b2 ? e2 : expr) = (b2 ? e2 : (b3 ? e3 : e4))
363 // expr = (b1 ? e1 : expr) = (b1 ? e1 : (b2 ? e2 : (b3 ? e3 : e4)))
364 //
365 // and end up with an appropriately chained tree.
366
367 ResultExpr expr = else_result;
368 for (const Clause& clause : clause_list_) {
369 expr = ResultExpr(
370 new const IfThenResultExprImpl(clause.first, clause.second, expr));
371 }
372 return expr;
373 }
374
375 ResultExpr SandboxBPFDSLPolicy::InvalidSyscall() const {
376 return Error(ENOSYS);
377 }
378
379 ResultExpr SandboxBPFDSLPolicy::Trap(TrapRegistry::TrapFnc trap_func,
380 const void* aux) {
381 return bpf_dsl::Trap(trap_func, aux);
382 }
383
384 } // namespace bpf_dsl
385 } // namespace sandbox
386
387 template class scoped_refptr<const sandbox::bpf_dsl::internal::BoolExprImpl>;
388 template class scoped_refptr<const sandbox::bpf_dsl::internal::ResultExprImpl>;
OLDNEW
« no previous file with comments | « sandbox/linux/bpf_dsl/bpf_dsl.h ('k') | sandbox/linux/bpf_dsl/bpf_dsl_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698