Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / sandbox / linux / bpf_dsl / bpf_dsl.cc
blob0d5aa553efa4c2b41ac72ec5be851bb5195b641f
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.
5 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
7 #include <limits>
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"
15 namespace sandbox {
16 namespace bpf_dsl {
17 namespace {
19 class AllowResultExprImpl : public internal::ResultExprImpl {
20 public:
21 AllowResultExprImpl() {}
23 ErrorCode Compile(PolicyCompiler* pc) const override {
24 return ErrorCode(ErrorCode::ERR_ALLOWED);
27 private:
28 ~AllowResultExprImpl() override {}
30 DISALLOW_COPY_AND_ASSIGN(AllowResultExprImpl);
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);
39 ErrorCode Compile(PolicyCompiler* pc) const override {
40 return pc->Error(err_);
43 private:
44 ~ErrorResultExprImpl() override {}
46 int err_;
48 DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl);
51 class KillResultExprImpl : public internal::ResultExprImpl {
52 public:
53 explicit KillResultExprImpl(const char* msg) : msg_(msg) { DCHECK(msg_); }
55 ErrorCode Compile(PolicyCompiler* pc) const override {
56 return pc->Kill(msg_);
59 private:
60 ~KillResultExprImpl() override {}
62 const char* msg_;
64 DISALLOW_COPY_AND_ASSIGN(KillResultExprImpl);
67 class TraceResultExprImpl : public internal::ResultExprImpl {
68 public:
69 TraceResultExprImpl(uint16_t aux) : aux_(aux) {}
71 ErrorCode Compile(PolicyCompiler* pc) const override {
72 return ErrorCode(ErrorCode::ERR_TRACE + aux_);
75 private:
76 ~TraceResultExprImpl() override {}
78 uint16_t aux_;
80 DISALLOW_COPY_AND_ASSIGN(TraceResultExprImpl);
83 class TrapResultExprImpl : public internal::ResultExprImpl {
84 public:
85 TrapResultExprImpl(TrapRegistry::TrapFnc func, const void* arg)
86 : func_(func), arg_(arg) {
87 DCHECK(func_);
90 ErrorCode Compile(PolicyCompiler* pc) const override {
91 return pc->Trap(func_, arg_);
94 private:
95 ~TrapResultExprImpl() override {}
97 TrapRegistry::TrapFnc func_;
98 const void* arg_;
100 DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl);
103 class UnsafeTrapResultExprImpl : public internal::ResultExprImpl {
104 public:
105 UnsafeTrapResultExprImpl(TrapRegistry::TrapFnc func, const void* arg)
106 : func_(func), arg_(arg) {
107 DCHECK(func_);
110 ErrorCode Compile(PolicyCompiler* pc) const override {
111 return pc->UnsafeTrap(func_, arg_);
114 bool HasUnsafeTraps() const override { return true; }
116 private:
117 ~UnsafeTrapResultExprImpl() override {}
119 TrapRegistry::TrapFnc func_;
120 const void* arg_;
122 DISALLOW_COPY_AND_ASSIGN(UnsafeTrapResultExprImpl);
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) {}
132 ErrorCode Compile(PolicyCompiler* pc) const override {
133 return cond_->Compile(
134 pc, then_result_->Compile(pc), else_result_->Compile(pc));
137 bool HasUnsafeTraps() const override {
138 return then_result_->HasUnsafeTraps() || else_result_->HasUnsafeTraps();
141 private:
142 ~IfThenResultExprImpl() override {}
144 BoolExpr cond_;
145 ResultExpr then_result_;
146 ResultExpr else_result_;
148 DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl);
151 class ConstBoolExprImpl : public internal::BoolExprImpl {
152 public:
153 ConstBoolExprImpl(bool value) : value_(value) {}
155 ErrorCode Compile(PolicyCompiler* pc,
156 ErrorCode true_ec,
157 ErrorCode false_ec) const override {
158 return value_ ? true_ec : false_ec;
161 private:
162 ~ConstBoolExprImpl() override {}
164 bool value_;
166 DISALLOW_COPY_AND_ASSIGN(ConstBoolExprImpl);
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) {}
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);
184 private:
185 ~PrimitiveBoolExprImpl() override {}
187 int argno_;
188 ErrorCode::ArgType is_32bit_;
189 uint64_t mask_;
190 uint64_t value_;
192 DISALLOW_COPY_AND_ASSIGN(PrimitiveBoolExprImpl);
195 class NegateBoolExprImpl : public internal::BoolExprImpl {
196 public:
197 explicit NegateBoolExprImpl(const BoolExpr& cond) : cond_(cond) {}
199 ErrorCode Compile(PolicyCompiler* pc,
200 ErrorCode true_ec,
201 ErrorCode false_ec) const override {
202 return cond_->Compile(pc, false_ec, true_ec);
205 private:
206 ~NegateBoolExprImpl() override {}
208 BoolExpr cond_;
210 DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl);
213 class AndBoolExprImpl : public internal::BoolExprImpl {
214 public:
215 AndBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
216 : lhs_(lhs), rhs_(rhs) {}
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);
224 private:
225 ~AndBoolExprImpl() override {}
227 BoolExpr lhs_;
228 BoolExpr rhs_;
230 DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl);
233 class OrBoolExprImpl : public internal::BoolExprImpl {
234 public:
235 OrBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
236 : lhs_(lhs), rhs_(rhs) {}
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));
244 private:
245 ~OrBoolExprImpl() override {}
247 BoolExpr lhs_;
248 BoolExpr rhs_;
250 DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl);
253 } // namespace
255 namespace internal {
257 bool ResultExprImpl::HasUnsafeTraps() const {
258 return false;
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;
273 BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) {
274 CHECK(size == 4 || size == 8);
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;
280 return BoolExpr(new const PrimitiveBoolExprImpl(num, arg_type, mask, val));
283 } // namespace internal
285 ResultExpr Allow() {
286 return ResultExpr(new const AllowResultExprImpl());
289 ResultExpr Error(int err) {
290 return ResultExpr(new const ErrorResultExprImpl(err));
293 ResultExpr Kill(const char* msg) {
294 return ResultExpr(new const KillResultExprImpl(msg));
297 ResultExpr Trace(uint16_t aux) {
298 return ResultExpr(new const TraceResultExprImpl(aux));
301 ResultExpr Trap(TrapRegistry::TrapFnc trap_func, const void* aux) {
302 return ResultExpr(new const TrapResultExprImpl(trap_func, aux));
305 ResultExpr UnsafeTrap(TrapRegistry::TrapFnc trap_func, const void* aux) {
306 return ResultExpr(new const UnsafeTrapResultExprImpl(trap_func, aux));
309 BoolExpr BoolConst(bool value) {
310 return BoolExpr(new const ConstBoolExprImpl(value));
313 BoolExpr operator!(const BoolExpr& cond) {
314 return BoolExpr(new const NegateBoolExprImpl(cond));
317 BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs) {
318 return BoolExpr(new const AndBoolExprImpl(lhs, rhs));
321 BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs) {
322 return BoolExpr(new const OrBoolExprImpl(lhs, rhs));
325 Elser If(const BoolExpr& cond, const ResultExpr& then_result) {
326 return Elser(nullptr).ElseIf(cond, then_result);
329 Elser::Elser(cons::List<Clause> clause_list) : clause_list_(clause_list) {
332 Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) {
335 Elser::~Elser() {
338 Elser Elser::ElseIf(const BoolExpr& cond, const ResultExpr& then_result) const {
339 return Elser(Cons(std::make_pair(cond, then_result), clause_list_));
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
349 // If(b1, e1).ElseIf(b2, e2).ElseIf(b3, e3).Else(e4)
351 // will have built up a list like
353 // [(b3, e3), (b2, e2), (b1, e1)].
355 // Now that we have e4, we can walk the list and create a ResultExpr
356 // tree like:
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)))
363 // and end up with an appropriately chained tree.
365 ResultExpr expr = else_result;
366 for (const Clause& clause : clause_list_) {
367 expr = ResultExpr(
368 new const IfThenResultExprImpl(clause.first, clause.second, expr));
370 return expr;
373 } // namespace bpf_dsl
374 } // namespace sandbox
376 template class scoped_refptr<const sandbox::bpf_dsl::internal::BoolExprImpl>;
377 template class scoped_refptr<const sandbox::bpf_dsl::internal::ResultExprImpl>;