summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h')
-rw-r--r--security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h155
1 files changed, 155 insertions, 0 deletions
diff --git a/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h b/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h
new file mode 100644
index 0000000000..2acf878474
--- /dev/null
+++ b/security/sandbox/chromium/sandbox/linux/bpf_dsl/policy_compiler.h
@@ -0,0 +1,155 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_
+#define SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <vector>
+
+#include "base/macros.h"
+#include "sandbox/linux/bpf_dsl/bpf_dsl_forward.h"
+#include "sandbox/linux/bpf_dsl/codegen.h"
+#include "sandbox/linux/bpf_dsl/trap_registry.h"
+#include "sandbox/sandbox_export.h"
+
+namespace sandbox {
+namespace bpf_dsl {
+class Policy;
+
+// PolicyCompiler implements the bpf_dsl compiler, allowing users to
+// transform bpf_dsl policies into BPF programs to be executed by the
+// Linux kernel.
+class SANDBOX_EXPORT PolicyCompiler {
+ public:
+ using PanicFunc = bpf_dsl::ResultExpr (*)(const char* error);
+
+ PolicyCompiler(const Policy* policy, TrapRegistry* registry);
+ ~PolicyCompiler();
+
+ // Compile registers any trap handlers needed by the policy and
+ // compiles the policy to a BPF program, which it returns.
+ CodeGen::Program Compile();
+
+ // DangerousSetEscapePC sets the "escape PC" that is allowed to issue any
+ // system calls, regardless of policy.
+ void DangerousSetEscapePC(uint64_t escapepc);
+
+ // SetPanicFunc sets the callback function used for handling faulty
+ // system call conditions. The default behavior is to immediately kill
+ // the process.
+ // TODO(mdempsky): Move this into Policy?
+ void SetPanicFunc(PanicFunc panic_func);
+
+ // UnsafeTraps require some syscalls to always be allowed.
+ // This helper function returns true for these calls.
+ static bool IsRequiredForUnsafeTrap(int sysno);
+
+ // Functions below are meant for use within bpf_dsl itself.
+
+ // Return returns a CodeGen::Node that returns the specified seccomp
+ // return value.
+ CodeGen::Node Return(uint32_t ret);
+
+ // Trap returns a CodeGen::Node to indicate the system call should
+ // instead invoke a trap handler.
+ CodeGen::Node Trap(TrapRegistry::TrapFnc fnc, const void* aux, bool safe);
+
+ // MaskedEqual returns a CodeGen::Node that represents a conditional branch.
+ // Argument "argno" (1..6) will be bitwise-AND'd with "mask" and compared
+ // to "value"; if equal, then "passed" will be executed, otherwise "failed".
+ // If "width" is 4, the argument must in the range of 0x0..(1u << 32 - 1)
+ // If it is outside this range, the sandbox treats the system call just
+ // the same as any other ABI violation (i.e., it panics).
+ CodeGen::Node MaskedEqual(int argno,
+ size_t width,
+ uint64_t mask,
+ uint64_t value,
+ CodeGen::Node passed,
+ CodeGen::Node failed);
+
+ private:
+ struct Range;
+ typedef std::vector<Range> Ranges;
+
+ // Used by MaskedEqualHalf to track which half of the argument it's
+ // emitting instructions for.
+ enum class ArgHalf {
+ LOWER,
+ UPPER,
+ };
+
+ // Compile the configured policy into a complete instruction sequence.
+ CodeGen::Node AssemblePolicy();
+
+ // Return an instruction sequence that checks the
+ // arch_seccomp_data's "arch" field is valid, and then passes
+ // control to |passed| if so.
+ CodeGen::Node CheckArch(CodeGen::Node passed);
+
+ // If |has_unsafe_traps_| is true, returns an instruction sequence
+ // that allows all system calls from |escapepc_|, and otherwise
+ // passes control to |rest|. Otherwise, simply returns |rest|.
+ CodeGen::Node MaybeAddEscapeHatch(CodeGen::Node rest);
+
+ // Return an instruction sequence that loads and checks the system
+ // call number, performs a binary search, and then dispatches to an
+ // appropriate instruction sequence compiled from the current
+ // policy.
+ CodeGen::Node DispatchSyscall();
+
+ // Return an instruction sequence that checks the system call number
+ // (expected to be loaded in register A) and if valid, passes
+ // control to |passed| (with register A still valid).
+ CodeGen::Node CheckSyscallNumber(CodeGen::Node passed);
+
+ // Finds all the ranges of system calls that need to be handled. Ranges are
+ // sorted in ascending order of system call numbers. There are no gaps in the
+ // ranges. System calls with identical CodeGen::Nodes are coalesced into a
+ // single
+ // range.
+ void FindRanges(Ranges* ranges);
+
+ // Returns a BPF program snippet that implements a jump table for the
+ // given range of system call numbers. This function runs recursively.
+ CodeGen::Node AssembleJumpTable(Ranges::const_iterator start,
+ Ranges::const_iterator stop);
+
+ // CompileResult compiles an individual result expression into a
+ // CodeGen node.
+ CodeGen::Node CompileResult(const ResultExpr& res);
+
+ // Returns a BPF program that evaluates half of a conditional expression;
+ // it should only ever be called from CondExpression().
+ CodeGen::Node MaskedEqualHalf(int argno,
+ size_t width,
+ uint64_t full_mask,
+ uint64_t full_value,
+ ArgHalf half,
+ CodeGen::Node passed,
+ CodeGen::Node failed);
+
+ // Returns the CodeGen::Node that is used to handle the case where a
+ // system call argument was expected to be a 32-bit type, but the
+ // value in the 64-bit register doesn't correspond to a
+ // zero-extended or sign-extended 32-bit value.
+ CodeGen::Node Unexpected64bitArgument(int argno);
+
+ const Policy* policy_;
+ TrapRegistry* registry_;
+ uint64_t escapepc_;
+ PanicFunc panic_func_;
+
+ CodeGen gen_;
+ bool has_unsafe_traps_;
+
+ DISALLOW_COPY_AND_ASSIGN(PolicyCompiler);
+};
+
+} // namespace bpf_dsl
+} // namespace sandbox
+
+#endif // SANDBOX_LINUX_BPF_DSL_POLICY_COMPILER_H_