Fix some lint errors in url_request_context_adapter
[chromium-blink-merge.git] / sandbox / linux / bpf_dsl / bpf_dsl.cc
blob66c054c2587abaa82573f8f0b1ae72d470563687
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 <errno.h>
9 #include <limits>
11 #include "base/logging.h"
12 #include "base/memory/ref_counted.h"
13 #include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h"
14 #include "sandbox/linux/seccomp-bpf/errorcode.h"
15 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
16 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
18 namespace sandbox {
19 namespace bpf_dsl {
20 namespace {
22 class AllowResultExprImpl : public internal::ResultExprImpl {
23 public:
24 AllowResultExprImpl() {}
26 virtual ErrorCode Compile(SandboxBPF* sb) const override {
27 return ErrorCode(ErrorCode::ERR_ALLOWED);
30 private:
31 virtual ~AllowResultExprImpl() {}
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 virtual ErrorCode Compile(SandboxBPF* sb) const override {
43 return sb->Error(err_);
46 private:
47 virtual ~ErrorResultExprImpl() {}
49 int err_;
51 DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl);
54 class KillResultExprImpl : public internal::ResultExprImpl {
55 public:
56 explicit KillResultExprImpl(const char* msg) : msg_(msg) { DCHECK(msg_); }
58 virtual ErrorCode Compile(SandboxBPF* sb) const override {
59 return sb->Kill(msg_);
62 private:
63 virtual ~KillResultExprImpl() {}
65 const char* msg_;
67 DISALLOW_COPY_AND_ASSIGN(KillResultExprImpl);
70 class TraceResultExprImpl : public internal::ResultExprImpl {
71 public:
72 TraceResultExprImpl(uint16_t aux) : aux_(aux) {}
74 virtual ErrorCode Compile(SandboxBPF* sb) const override {
75 return ErrorCode(ErrorCode::ERR_TRACE + aux_);
78 private:
79 virtual ~TraceResultExprImpl() {}
81 uint16_t aux_;
83 DISALLOW_COPY_AND_ASSIGN(TraceResultExprImpl);
86 class TrapResultExprImpl : public internal::ResultExprImpl {
87 public:
88 TrapResultExprImpl(Trap::TrapFnc func, const void* arg)
89 : func_(func), arg_(arg) {
90 DCHECK(func_);
93 virtual ErrorCode Compile(SandboxBPF* sb) const override {
94 return sb->Trap(func_, arg_);
97 private:
98 virtual ~TrapResultExprImpl() {}
100 Trap::TrapFnc func_;
101 const void* arg_;
103 DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl);
106 class UnsafeTrapResultExprImpl : public internal::ResultExprImpl {
107 public:
108 UnsafeTrapResultExprImpl(Trap::TrapFnc func, const void* arg)
109 : func_(func), arg_(arg) {
110 DCHECK(func_);
113 virtual ErrorCode Compile(SandboxBPF* sb) const override {
114 return sb->UnsafeTrap(func_, arg_);
117 virtual bool HasUnsafeTraps() const override { return true; }
119 private:
120 virtual ~UnsafeTrapResultExprImpl() {}
122 Trap::TrapFnc func_;
123 const void* arg_;
125 DISALLOW_COPY_AND_ASSIGN(UnsafeTrapResultExprImpl);
128 class IfThenResultExprImpl : public internal::ResultExprImpl {
129 public:
130 IfThenResultExprImpl(const BoolExpr& cond,
131 const ResultExpr& then_result,
132 const ResultExpr& else_result)
133 : cond_(cond), then_result_(then_result), else_result_(else_result) {}
135 virtual ErrorCode Compile(SandboxBPF* sb) const override {
136 return cond_->Compile(
137 sb, then_result_->Compile(sb), else_result_->Compile(sb));
140 virtual bool HasUnsafeTraps() const override {
141 return then_result_->HasUnsafeTraps() || else_result_->HasUnsafeTraps();
144 private:
145 virtual ~IfThenResultExprImpl() {}
147 BoolExpr cond_;
148 ResultExpr then_result_;
149 ResultExpr else_result_;
151 DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl);
154 class ConstBoolExprImpl : public internal::BoolExprImpl {
155 public:
156 ConstBoolExprImpl(bool value) : value_(value) {}
158 virtual ErrorCode Compile(SandboxBPF* sb,
159 ErrorCode true_ec,
160 ErrorCode false_ec) const override {
161 return value_ ? true_ec : false_ec;
164 private:
165 virtual ~ConstBoolExprImpl() {}
167 bool value_;
169 DISALLOW_COPY_AND_ASSIGN(ConstBoolExprImpl);
172 class PrimitiveBoolExprImpl : public internal::BoolExprImpl {
173 public:
174 PrimitiveBoolExprImpl(int argno,
175 ErrorCode::ArgType is_32bit,
176 uint64_t mask,
177 uint64_t value)
178 : argno_(argno), is_32bit_(is_32bit), mask_(mask), value_(value) {}
180 virtual ErrorCode Compile(SandboxBPF* sb,
181 ErrorCode true_ec,
182 ErrorCode false_ec) const override {
183 return sb->CondMaskedEqual(
184 argno_, is_32bit_, mask_, value_, true_ec, false_ec);
187 private:
188 virtual ~PrimitiveBoolExprImpl() {}
190 int argno_;
191 ErrorCode::ArgType is_32bit_;
192 uint64_t mask_;
193 uint64_t value_;
195 DISALLOW_COPY_AND_ASSIGN(PrimitiveBoolExprImpl);
198 class NegateBoolExprImpl : public internal::BoolExprImpl {
199 public:
200 explicit NegateBoolExprImpl(const BoolExpr& cond) : cond_(cond) {}
202 virtual ErrorCode Compile(SandboxBPF* sb,
203 ErrorCode true_ec,
204 ErrorCode false_ec) const override {
205 return cond_->Compile(sb, false_ec, true_ec);
208 private:
209 virtual ~NegateBoolExprImpl() {}
211 BoolExpr cond_;
213 DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl);
216 class AndBoolExprImpl : public internal::BoolExprImpl {
217 public:
218 AndBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
219 : lhs_(lhs), rhs_(rhs) {}
221 virtual ErrorCode Compile(SandboxBPF* sb,
222 ErrorCode true_ec,
223 ErrorCode false_ec) const override {
224 return lhs_->Compile(sb, rhs_->Compile(sb, true_ec, false_ec), false_ec);
227 private:
228 virtual ~AndBoolExprImpl() {}
230 BoolExpr lhs_;
231 BoolExpr rhs_;
233 DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl);
236 class OrBoolExprImpl : public internal::BoolExprImpl {
237 public:
238 OrBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
239 : lhs_(lhs), rhs_(rhs) {}
241 virtual ErrorCode Compile(SandboxBPF* sb,
242 ErrorCode true_ec,
243 ErrorCode false_ec) const override {
244 return lhs_->Compile(sb, true_ec, rhs_->Compile(sb, true_ec, false_ec));
247 private:
248 virtual ~OrBoolExprImpl() {}
250 BoolExpr lhs_;
251 BoolExpr rhs_;
253 DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl);
256 } // namespace
258 namespace internal {
260 bool ResultExprImpl::HasUnsafeTraps() const {
261 return false;
264 uint64_t DefaultMask(size_t size) {
265 switch (size) {
266 case 4:
267 return std::numeric_limits<uint32_t>::max();
268 case 8:
269 return std::numeric_limits<uint64_t>::max();
270 default:
271 CHECK(false) << "Unimplemented DefaultMask case";
272 return 0;
276 BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) {
277 CHECK(size == 4 || size == 8);
279 // TODO(mdempsky): Should we just always use TP_64BIT?
280 const ErrorCode::ArgType arg_type =
281 (size == 4) ? ErrorCode::TP_32BIT : ErrorCode::TP_64BIT;
283 return BoolExpr(new const PrimitiveBoolExprImpl(num, arg_type, mask, val));
286 } // namespace internal
288 ResultExpr Allow() {
289 return ResultExpr(new const AllowResultExprImpl());
292 ResultExpr Error(int err) {
293 return ResultExpr(new const ErrorResultExprImpl(err));
296 ResultExpr Kill(const char* msg) {
297 return ResultExpr(new const KillResultExprImpl(msg));
300 ResultExpr Trace(uint16_t aux) {
301 return ResultExpr(new const TraceResultExprImpl(aux));
304 ResultExpr Trap(Trap::TrapFnc trap_func, const void* aux) {
305 return ResultExpr(new const TrapResultExprImpl(trap_func, aux));
308 ResultExpr UnsafeTrap(Trap::TrapFnc trap_func, const void* aux) {
309 return ResultExpr(new const UnsafeTrapResultExprImpl(trap_func, aux));
312 BoolExpr BoolConst(bool value) {
313 return BoolExpr(new const ConstBoolExprImpl(value));
316 BoolExpr operator!(const BoolExpr& cond) {
317 return BoolExpr(new const NegateBoolExprImpl(cond));
320 BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs) {
321 return BoolExpr(new const AndBoolExprImpl(lhs, rhs));
324 BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs) {
325 return BoolExpr(new const OrBoolExprImpl(lhs, rhs));
328 Elser If(const BoolExpr& cond, const ResultExpr& then_result) {
329 return Elser(nullptr).ElseIf(cond, then_result);
332 Elser::Elser(cons::List<Clause> clause_list) : clause_list_(clause_list) {
335 Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) {
338 Elser::~Elser() {
341 Elser Elser::ElseIf(const BoolExpr& cond, const ResultExpr& then_result) const {
342 return Elser(Cons(std::make_pair(cond, then_result), clause_list_));
345 ResultExpr Elser::Else(const ResultExpr& else_result) const {
346 // We finally have the default result expression for this
347 // if/then/else sequence. Also, we've already accumulated all
348 // if/then pairs into a list of reverse order (i.e., lower priority
349 // conditions are listed before higher priority ones). E.g., an
350 // expression like
352 // If(b1, e1).ElseIf(b2, e2).ElseIf(b3, e3).Else(e4)
354 // will have built up a list like
356 // [(b3, e3), (b2, e2), (b1, e1)].
358 // Now that we have e4, we can walk the list and create a ResultExpr
359 // tree like:
361 // expr = e4
362 // expr = (b3 ? e3 : expr) = (b3 ? e3 : e4)
363 // expr = (b2 ? e2 : expr) = (b2 ? e2 : (b3 ? e3 : e4))
364 // expr = (b1 ? e1 : expr) = (b1 ? e1 : (b2 ? e2 : (b3 ? e3 : e4)))
366 // and end up with an appropriately chained tree.
368 ResultExpr expr = else_result;
369 for (const Clause& clause : clause_list_) {
370 expr = ResultExpr(
371 new const IfThenResultExprImpl(clause.first, clause.second, expr));
373 return expr;
376 ResultExpr SandboxBPFDSLPolicy::InvalidSyscall() const {
377 return Error(ENOSYS);
380 ErrorCode SandboxBPFDSLPolicy::EvaluateSyscall(SandboxBPF* sb,
381 int sysno) const {
382 return EvaluateSyscall(sysno)->Compile(sb);
385 ErrorCode SandboxBPFDSLPolicy::InvalidSyscall(SandboxBPF* sb) const {
386 return InvalidSyscall()->Compile(sb);
389 bool SandboxBPFDSLPolicy::HasUnsafeTraps() const {
390 for (SyscallIterator iter(false); !iter.Done();) {
391 uint32_t sysnum = iter.Next();
392 if (SyscallIterator::IsValid(sysnum) &&
393 EvaluateSyscall(sysnum)->HasUnsafeTraps()) {
394 return true;
397 return InvalidSyscall()->HasUnsafeTraps();
400 ResultExpr SandboxBPFDSLPolicy::Trap(Trap::TrapFnc trap_func, const void* aux) {
401 return bpf_dsl::Trap(trap_func, aux);
404 } // namespace bpf_dsl
405 } // namespace sandbox
407 template class scoped_refptr<const sandbox::bpf_dsl::internal::BoolExprImpl>;
408 template class scoped_refptr<const sandbox::bpf_dsl::internal::ResultExprImpl>;