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