Permission message rules: Each rule must have >= 1 required permissions
[chromium-blink-merge.git] / sandbox / linux / bpf_dsl / policy_compiler.h
blobf0979417663246bce22006aa6941a416787922da
1 // Copyright (c) 2012 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 #ifndef SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_
6 #define SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_
8 #include <stdint.h>
10 #include <map>
11 #include <set>
12 #include <vector>
14 #include "base/macros.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h"
17 #include "sandbox/linux/bpf_dsl/codegen.h"
18 #include "sandbox/linux/bpf_dsl/errorcode.h"
19 #include "sandbox/linux/bpf_dsl/trap_registry.h"
20 #include "sandbox/sandbox_export.h"
22 namespace sandbox {
23 namespace bpf_dsl {
24 class Policy;
26 // PolicyCompiler implements the bpf_dsl compiler, allowing users to
27 // transform bpf_dsl policies into BPF programs to be executed by the
28 // Linux kernel.
29 class SANDBOX_EXPORT PolicyCompiler {
30 public:
31 using PanicFunc = bpf_dsl::ResultExpr (*)(const char* error);
33 PolicyCompiler(const Policy* policy, TrapRegistry* registry);
34 ~PolicyCompiler();
36 // Compile registers any trap handlers needed by the policy and
37 // compiles the policy to a BPF program, which it returns.
38 scoped_ptr<CodeGen::Program> Compile();
40 // DangerousSetEscapePC sets the "escape PC" that is allowed to issue any
41 // system calls, regardless of policy.
42 void DangerousSetEscapePC(uint64_t escapepc);
44 // SetPanicFunc sets the callback function used for handling faulty
45 // system call conditions. The default behavior is to immediately kill
46 // the process.
47 // TODO(mdempsky): Move this into Policy?
48 void SetPanicFunc(PanicFunc panic_func);
50 // Error returns an ErrorCode to indicate the system call should fail with
51 // the specified error number.
52 ErrorCode Error(int err);
54 // Trap returns an ErrorCode to indicate the system call should
55 // instead invoke a trap handler.
56 ErrorCode Trap(TrapRegistry::TrapFnc fnc, const void* aux, bool safe);
58 // UnsafeTraps require some syscalls to always be allowed.
59 // This helper function returns true for these calls.
60 static bool IsRequiredForUnsafeTrap(int sysno);
62 // We can also use ErrorCode to request evaluation of a conditional
63 // statement based on inspection of system call parameters.
64 // This method wrap an ErrorCode object around the conditional statement.
65 // Argument "argno" (1..6) will be bitwise-AND'd with "mask" and compared
66 // to "value"; if equal, then "passed" will be returned, otherwise "failed".
67 // If "is32bit" is set, the argument must in the range of 0x0..(1u << 32 - 1)
68 // If it is outside this range, the sandbox treats the system call just
69 // the same as any other ABI violation (i.e. it aborts with an error
70 // message).
71 ErrorCode CondMaskedEqual(int argno,
72 ErrorCode::ArgType is_32bit,
73 uint64_t mask,
74 uint64_t value,
75 const ErrorCode& passed,
76 const ErrorCode& failed);
78 // Returns the fatal ErrorCode that is used to indicate that somebody
79 // attempted to pass a 64bit value in a 32bit system call argument.
80 // This method is primarily needed for testing purposes.
81 ErrorCode Unexpected64bitArgument();
83 private:
84 struct Range;
85 typedef std::vector<Range> Ranges;
86 typedef std::set<ErrorCode, struct ErrorCode::LessThan> Conds;
88 // Used by CondExpressionHalf to track which half of the argument it's
89 // emitting instructions for.
90 enum ArgHalf {
91 LowerHalf,
92 UpperHalf,
95 // Compile the configured policy into a complete instruction sequence.
96 CodeGen::Node AssemblePolicy();
98 // Return an instruction sequence that checks the
99 // arch_seccomp_data's "arch" field is valid, and then passes
100 // control to |passed| if so.
101 CodeGen::Node CheckArch(CodeGen::Node passed);
103 // If |has_unsafe_traps_| is true, returns an instruction sequence
104 // that allows all system calls from |escapepc_|, and otherwise
105 // passes control to |rest|. Otherwise, simply returns |rest|.
106 CodeGen::Node MaybeAddEscapeHatch(CodeGen::Node rest);
108 // Return an instruction sequence that loads and checks the system
109 // call number, performs a binary search, and then dispatches to an
110 // appropriate instruction sequence compiled from the current
111 // policy.
112 CodeGen::Node DispatchSyscall();
114 // Return an instruction sequence that checks the system call number
115 // (expected to be loaded in register A) and if valid, passes
116 // control to |passed| (with register A still valid).
117 CodeGen::Node CheckSyscallNumber(CodeGen::Node passed);
119 // Finds all the ranges of system calls that need to be handled. Ranges are
120 // sorted in ascending order of system call numbers. There are no gaps in the
121 // ranges. System calls with identical ErrorCodes are coalesced into a single
122 // range.
123 void FindRanges(Ranges* ranges);
125 // Returns a BPF program snippet that implements a jump table for the
126 // given range of system call numbers. This function runs recursively.
127 CodeGen::Node AssembleJumpTable(Ranges::const_iterator start,
128 Ranges::const_iterator stop);
130 // CompileResult compiles an individual result expression into a
131 // CodeGen node.
132 CodeGen::Node CompileResult(const ResultExpr& res);
134 // Returns a BPF program snippet that makes the BPF filter program exit
135 // with the given ErrorCode "err". N.B. the ErrorCode may very well be a
136 // conditional expression; if so, this function will recursively call
137 // CondExpression() and possibly RetExpression() to build a complex set of
138 // instructions.
139 CodeGen::Node RetExpression(const ErrorCode& err);
141 // Returns a BPF program that evaluates the conditional expression in
142 // "cond" and returns the appropriate value from the BPF filter program.
143 // This function recursively calls RetExpression(); it should only ever be
144 // called from RetExpression().
145 CodeGen::Node CondExpression(const ErrorCode& cond);
147 // Returns a BPF program that evaluates half of a conditional expression;
148 // it should only ever be called from CondExpression().
149 CodeGen::Node CondExpressionHalf(const ErrorCode& cond,
150 ArgHalf half,
151 CodeGen::Node passed,
152 CodeGen::Node failed);
154 const Policy* policy_;
155 TrapRegistry* registry_;
156 uint64_t escapepc_;
157 PanicFunc panic_func_;
159 Conds conds_;
160 CodeGen gen_;
161 bool has_unsafe_traps_;
163 DISALLOW_COPY_AND_ASSIGN(PolicyCompiler);
166 } // namespace bpf_dsl
167 } // namespace sandbox
169 #endif // SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_