Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / sandbox / linux / bpf_dsl / bpf_dsl.cc
blob276aaf6e04f28f4bf456eae709401e52544c5807
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"
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 bool IsAllow() const override { return true; }
29 private:
30 ~AllowResultExprImpl() override {}
32 DISALLOW_COPY_AND_ASSIGN(AllowResultExprImpl);
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);
41 ErrorCode Compile(PolicyCompiler* pc) const override {
42 return pc->Error(err_);
45 bool IsDeny() const override { return true; }
47 private:
48 ~ErrorResultExprImpl() override {}
50 int err_;
52 DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl);
55 class KillResultExprImpl : public internal::ResultExprImpl {
56 public:
57 KillResultExprImpl() {}
59 ErrorCode Compile(PolicyCompiler* pc) const override {
60 return ErrorCode(ErrorCode::ERR_KILL);
63 bool IsDeny() const override { return true; }
65 private:
66 ~KillResultExprImpl() override {}
68 DISALLOW_COPY_AND_ASSIGN(KillResultExprImpl);
71 class TraceResultExprImpl : public internal::ResultExprImpl {
72 public:
73 TraceResultExprImpl(uint16_t aux) : aux_(aux) {}
75 ErrorCode Compile(PolicyCompiler* pc) const override {
76 return ErrorCode(ErrorCode::ERR_TRACE + aux_);
79 private:
80 ~TraceResultExprImpl() override {}
82 uint16_t aux_;
84 DISALLOW_COPY_AND_ASSIGN(TraceResultExprImpl);
87 class TrapResultExprImpl : public internal::ResultExprImpl {
88 public:
89 TrapResultExprImpl(TrapRegistry::TrapFnc func, const void* arg, bool safe)
90 : func_(func), arg_(arg), safe_(safe) {
91 DCHECK(func_);
94 ErrorCode Compile(PolicyCompiler* pc) const override {
95 return pc->Trap(func_, arg_, safe_);
98 bool HasUnsafeTraps() const override { return safe_ == false; }
100 bool IsDeny() const override { return true; }
102 private:
103 ~TrapResultExprImpl() override {}
105 TrapRegistry::TrapFnc func_;
106 const void* arg_;
107 bool safe_;
109 DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl);
112 class IfThenResultExprImpl : public internal::ResultExprImpl {
113 public:
114 IfThenResultExprImpl(const BoolExpr& cond,
115 const ResultExpr& then_result,
116 const ResultExpr& else_result)
117 : cond_(cond), then_result_(then_result), else_result_(else_result) {}
119 ErrorCode Compile(PolicyCompiler* pc) const override {
120 return cond_->Compile(
121 pc, then_result_->Compile(pc), else_result_->Compile(pc));
124 bool HasUnsafeTraps() const override {
125 return then_result_->HasUnsafeTraps() || else_result_->HasUnsafeTraps();
128 private:
129 ~IfThenResultExprImpl() override {}
131 BoolExpr cond_;
132 ResultExpr then_result_;
133 ResultExpr else_result_;
135 DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl);
138 class ConstBoolExprImpl : public internal::BoolExprImpl {
139 public:
140 ConstBoolExprImpl(bool value) : value_(value) {}
142 ErrorCode Compile(PolicyCompiler* pc,
143 ErrorCode true_ec,
144 ErrorCode false_ec) const override {
145 return value_ ? true_ec : false_ec;
148 private:
149 ~ConstBoolExprImpl() override {}
151 bool value_;
153 DISALLOW_COPY_AND_ASSIGN(ConstBoolExprImpl);
156 class PrimitiveBoolExprImpl : public internal::BoolExprImpl {
157 public:
158 PrimitiveBoolExprImpl(int argno,
159 ErrorCode::ArgType is_32bit,
160 uint64_t mask,
161 uint64_t value)
162 : argno_(argno), is_32bit_(is_32bit), mask_(mask), value_(value) {}
164 ErrorCode Compile(PolicyCompiler* pc,
165 ErrorCode true_ec,
166 ErrorCode false_ec) const override {
167 return pc->CondMaskedEqual(
168 argno_, is_32bit_, mask_, value_, true_ec, false_ec);
171 private:
172 ~PrimitiveBoolExprImpl() override {}
174 int argno_;
175 ErrorCode::ArgType is_32bit_;
176 uint64_t mask_;
177 uint64_t value_;
179 DISALLOW_COPY_AND_ASSIGN(PrimitiveBoolExprImpl);
182 class NegateBoolExprImpl : public internal::BoolExprImpl {
183 public:
184 explicit NegateBoolExprImpl(const BoolExpr& cond) : cond_(cond) {}
186 ErrorCode Compile(PolicyCompiler* pc,
187 ErrorCode true_ec,
188 ErrorCode false_ec) const override {
189 return cond_->Compile(pc, false_ec, true_ec);
192 private:
193 ~NegateBoolExprImpl() override {}
195 BoolExpr cond_;
197 DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl);
200 class AndBoolExprImpl : public internal::BoolExprImpl {
201 public:
202 AndBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
203 : lhs_(lhs), rhs_(rhs) {}
205 ErrorCode Compile(PolicyCompiler* pc,
206 ErrorCode true_ec,
207 ErrorCode false_ec) const override {
208 return lhs_->Compile(pc, rhs_->Compile(pc, true_ec, false_ec), false_ec);
211 private:
212 ~AndBoolExprImpl() override {}
214 BoolExpr lhs_;
215 BoolExpr rhs_;
217 DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl);
220 class OrBoolExprImpl : public internal::BoolExprImpl {
221 public:
222 OrBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
223 : lhs_(lhs), rhs_(rhs) {}
225 ErrorCode Compile(PolicyCompiler* pc,
226 ErrorCode true_ec,
227 ErrorCode false_ec) const override {
228 return lhs_->Compile(pc, true_ec, rhs_->Compile(pc, true_ec, false_ec));
231 private:
232 ~OrBoolExprImpl() override {}
234 BoolExpr lhs_;
235 BoolExpr rhs_;
237 DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl);
240 } // namespace
242 namespace internal {
244 bool ResultExprImpl::HasUnsafeTraps() const {
245 return false;
248 bool ResultExprImpl::IsAllow() const {
249 return false;
252 bool ResultExprImpl::IsDeny() const {
253 return false;
256 uint64_t DefaultMask(size_t size) {
257 switch (size) {
258 case 4:
259 return std::numeric_limits<uint32_t>::max();
260 case 8:
261 return std::numeric_limits<uint64_t>::max();
262 default:
263 CHECK(false) << "Unimplemented DefaultMask case";
264 return 0;
268 BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) {
269 // If this is changed, update Arg<T>::EqualTo's static_cast rules
270 // accordingly.
271 CHECK(size == 4 || size == 8);
273 // TODO(mdempsky): Should we just always use TP_64BIT?
274 const ErrorCode::ArgType arg_type =
275 (size == 4) ? ErrorCode::TP_32BIT : ErrorCode::TP_64BIT;
277 return BoolExpr(new const PrimitiveBoolExprImpl(num, arg_type, mask, val));
280 } // namespace internal
282 ResultExpr Allow() {
283 return ResultExpr(new const AllowResultExprImpl());
286 ResultExpr Error(int err) {
287 return ResultExpr(new const ErrorResultExprImpl(err));
290 ResultExpr Kill() {
291 return ResultExpr(new const KillResultExprImpl());
294 ResultExpr Trace(uint16_t aux) {
295 return ResultExpr(new const TraceResultExprImpl(aux));
298 ResultExpr Trap(TrapRegistry::TrapFnc trap_func, const void* aux) {
299 return ResultExpr(
300 new const TrapResultExprImpl(trap_func, aux, true /* safe */));
303 ResultExpr UnsafeTrap(TrapRegistry::TrapFnc trap_func, const void* aux) {
304 return ResultExpr(
305 new const TrapResultExprImpl(trap_func, aux, false /* unsafe */));
308 BoolExpr BoolConst(bool value) {
309 return BoolExpr(new const ConstBoolExprImpl(value));
312 BoolExpr operator!(const BoolExpr& cond) {
313 return BoolExpr(new const NegateBoolExprImpl(cond));
316 BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs) {
317 return BoolExpr(new const AndBoolExprImpl(lhs, rhs));
320 BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs) {
321 return BoolExpr(new const OrBoolExprImpl(lhs, rhs));
324 Elser If(const BoolExpr& cond, const ResultExpr& then_result) {
325 return Elser(nullptr).ElseIf(cond, then_result);
328 Elser::Elser(cons::List<Clause> clause_list) : clause_list_(clause_list) {
331 Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) {
334 Elser::~Elser() {
337 Elser Elser::ElseIf(const BoolExpr& cond, const ResultExpr& then_result) const {
338 return Elser(Cons(std::make_pair(cond, then_result), clause_list_));
341 ResultExpr Elser::Else(const ResultExpr& else_result) const {
342 // We finally have the default result expression for this
343 // if/then/else sequence. Also, we've already accumulated all
344 // if/then pairs into a list of reverse order (i.e., lower priority
345 // conditions are listed before higher priority ones). E.g., an
346 // expression like
348 // If(b1, e1).ElseIf(b2, e2).ElseIf(b3, e3).Else(e4)
350 // will have built up a list like
352 // [(b3, e3), (b2, e2), (b1, e1)].
354 // Now that we have e4, we can walk the list and create a ResultExpr
355 // tree like:
357 // expr = e4
358 // expr = (b3 ? e3 : expr) = (b3 ? e3 : e4)
359 // expr = (b2 ? e2 : expr) = (b2 ? e2 : (b3 ? e3 : e4))
360 // expr = (b1 ? e1 : expr) = (b1 ? e1 : (b2 ? e2 : (b3 ? e3 : e4)))
362 // and end up with an appropriately chained tree.
364 ResultExpr expr = else_result;
365 for (const Clause& clause : clause_list_) {
366 expr = ResultExpr(
367 new const IfThenResultExprImpl(clause.first, clause.second, expr));
369 return expr;
372 } // namespace bpf_dsl
373 } // namespace sandbox
375 template class scoped_refptr<const sandbox::bpf_dsl::internal::BoolExprImpl>;
376 template class scoped_refptr<const sandbox::bpf_dsl::internal::ResultExprImpl>;