cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / sandbox / linux / bpf_dsl / bpf_dsl.cc
blob3772efb2c703d4756746ff3cdf137a8d7d943177
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/errorcode.h"
13 #include "sandbox/linux/bpf_dsl/policy_compiler.h"
14 #include "sandbox/linux/system_headers/linux_seccomp.h"
16 namespace sandbox {
17 namespace bpf_dsl {
18 namespace {
20 class AllowResultExprImpl : public internal::ResultExprImpl {
21 public:
22 AllowResultExprImpl() {}
24 CodeGen::Node Compile(PolicyCompiler* pc) const override {
25 return pc->Return(SECCOMP_RET_ALLOW);
28 bool IsAllow() const override { return true; }
30 private:
31 ~AllowResultExprImpl() override {}
33 DISALLOW_COPY_AND_ASSIGN(AllowResultExprImpl);
36 class ErrorResultExprImpl : public internal::ResultExprImpl {
37 public:
38 explicit ErrorResultExprImpl(int err) : err_(err) {
39 CHECK(err_ >= ErrorCode::ERR_MIN_ERRNO && err_ <= ErrorCode::ERR_MAX_ERRNO);
42 CodeGen::Node Compile(PolicyCompiler* pc) const override {
43 return pc->Return(SECCOMP_RET_ERRNO + err_);
46 bool IsDeny() const override { return true; }
48 private:
49 ~ErrorResultExprImpl() override {}
51 int err_;
53 DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl);
56 class KillResultExprImpl : public internal::ResultExprImpl {
57 public:
58 KillResultExprImpl() {}
60 CodeGen::Node Compile(PolicyCompiler* pc) const override {
61 return pc->Return(SECCOMP_RET_KILL);
64 bool IsDeny() const override { return true; }
66 private:
67 ~KillResultExprImpl() override {}
69 DISALLOW_COPY_AND_ASSIGN(KillResultExprImpl);
72 class TraceResultExprImpl : public internal::ResultExprImpl {
73 public:
74 TraceResultExprImpl(uint16_t aux) : aux_(aux) {}
76 CodeGen::Node Compile(PolicyCompiler* pc) const override {
77 return pc->Return(SECCOMP_RET_TRACE + aux_);
80 private:
81 ~TraceResultExprImpl() override {}
83 uint16_t aux_;
85 DISALLOW_COPY_AND_ASSIGN(TraceResultExprImpl);
88 class TrapResultExprImpl : public internal::ResultExprImpl {
89 public:
90 TrapResultExprImpl(TrapRegistry::TrapFnc func, const void* arg, bool safe)
91 : func_(func), arg_(arg), safe_(safe) {
92 DCHECK(func_);
95 CodeGen::Node Compile(PolicyCompiler* pc) const override {
96 return pc->Trap(func_, arg_, safe_);
99 bool HasUnsafeTraps() const override { return safe_ == false; }
101 bool IsDeny() const override { return true; }
103 private:
104 ~TrapResultExprImpl() override {}
106 TrapRegistry::TrapFnc func_;
107 const void* arg_;
108 bool safe_;
110 DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl);
113 class IfThenResultExprImpl : public internal::ResultExprImpl {
114 public:
115 IfThenResultExprImpl(const BoolExpr& cond,
116 const ResultExpr& then_result,
117 const ResultExpr& else_result)
118 : cond_(cond), then_result_(then_result), else_result_(else_result) {}
120 CodeGen::Node Compile(PolicyCompiler* pc) const override {
121 // We compile the "then" and "else" expressions in separate statements so
122 // they have a defined sequencing. See https://crbug.com/529480.
123 CodeGen::Node then_node = then_result_->Compile(pc);
124 CodeGen::Node else_node = else_result_->Compile(pc);
125 return cond_->Compile(pc, then_node, else_node);
128 bool HasUnsafeTraps() const override {
129 return then_result_->HasUnsafeTraps() || else_result_->HasUnsafeTraps();
132 private:
133 ~IfThenResultExprImpl() override {}
135 BoolExpr cond_;
136 ResultExpr then_result_;
137 ResultExpr else_result_;
139 DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl);
142 class ConstBoolExprImpl : public internal::BoolExprImpl {
143 public:
144 ConstBoolExprImpl(bool value) : value_(value) {}
146 CodeGen::Node Compile(PolicyCompiler* pc,
147 CodeGen::Node then_node,
148 CodeGen::Node else_node) const override {
149 return value_ ? then_node : else_node;
152 private:
153 ~ConstBoolExprImpl() override {}
155 bool value_;
157 DISALLOW_COPY_AND_ASSIGN(ConstBoolExprImpl);
160 class MaskedEqualBoolExprImpl : public internal::BoolExprImpl {
161 public:
162 MaskedEqualBoolExprImpl(int argno,
163 size_t width,
164 uint64_t mask,
165 uint64_t value)
166 : argno_(argno), width_(width), mask_(mask), value_(value) {}
168 CodeGen::Node Compile(PolicyCompiler* pc,
169 CodeGen::Node then_node,
170 CodeGen::Node else_node) const override {
171 return pc->MaskedEqual(argno_, width_, mask_, value_, then_node, else_node);
174 private:
175 ~MaskedEqualBoolExprImpl() override {}
177 int argno_;
178 size_t width_;
179 uint64_t mask_;
180 uint64_t value_;
182 DISALLOW_COPY_AND_ASSIGN(MaskedEqualBoolExprImpl);
185 class NegateBoolExprImpl : public internal::BoolExprImpl {
186 public:
187 explicit NegateBoolExprImpl(const BoolExpr& cond) : cond_(cond) {}
189 CodeGen::Node Compile(PolicyCompiler* pc,
190 CodeGen::Node then_node,
191 CodeGen::Node else_node) const override {
192 return cond_->Compile(pc, else_node, then_node);
195 private:
196 ~NegateBoolExprImpl() override {}
198 BoolExpr cond_;
200 DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl);
203 class AndBoolExprImpl : public internal::BoolExprImpl {
204 public:
205 AndBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
206 : lhs_(lhs), rhs_(rhs) {}
208 CodeGen::Node Compile(PolicyCompiler* pc,
209 CodeGen::Node then_node,
210 CodeGen::Node else_node) const override {
211 return lhs_->Compile(pc, rhs_->Compile(pc, then_node, else_node),
212 else_node);
215 private:
216 ~AndBoolExprImpl() override {}
218 BoolExpr lhs_;
219 BoolExpr rhs_;
221 DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl);
224 class OrBoolExprImpl : public internal::BoolExprImpl {
225 public:
226 OrBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
227 : lhs_(lhs), rhs_(rhs) {}
229 CodeGen::Node Compile(PolicyCompiler* pc,
230 CodeGen::Node then_node,
231 CodeGen::Node else_node) const override {
232 return lhs_->Compile(pc, then_node,
233 rhs_->Compile(pc, then_node, else_node));
236 private:
237 ~OrBoolExprImpl() override {}
239 BoolExpr lhs_;
240 BoolExpr rhs_;
242 DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl);
245 } // namespace
247 namespace internal {
249 bool ResultExprImpl::HasUnsafeTraps() const {
250 return false;
253 bool ResultExprImpl::IsAllow() const {
254 return false;
257 bool ResultExprImpl::IsDeny() 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 // If this is changed, update Arg<T>::EqualTo's static_cast rules
275 // accordingly.
276 CHECK(size == 4 || size == 8);
278 return BoolExpr(new const MaskedEqualBoolExprImpl(num, size, mask, val));
281 } // namespace internal
283 ResultExpr Allow() {
284 return ResultExpr(new const AllowResultExprImpl());
287 ResultExpr Error(int err) {
288 return ResultExpr(new const ErrorResultExprImpl(err));
291 ResultExpr Kill() {
292 return ResultExpr(new const KillResultExprImpl());
295 ResultExpr Trace(uint16_t aux) {
296 return ResultExpr(new const TraceResultExprImpl(aux));
299 ResultExpr Trap(TrapRegistry::TrapFnc trap_func, const void* aux) {
300 return ResultExpr(
301 new const TrapResultExprImpl(trap_func, aux, true /* safe */));
304 ResultExpr UnsafeTrap(TrapRegistry::TrapFnc trap_func, const void* aux) {
305 return ResultExpr(
306 new const TrapResultExprImpl(trap_func, aux, false /* unsafe */));
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>;