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