// 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 <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 fatal CodeGen::Node that is used to indicate that somebody
  // attempted to pass a 64bit value in a 32bit system call argument.
  CodeGen::Node Unexpected64bitArgument();

  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_
