// 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.

#include "sandbox/linux/bpf_dsl/policy_compiler.h"

#include <errno.h>
#include <linux/filter.h>
#include <sys/syscall.h>

#include <limits>

#include "base/logging.h"
#include "base/macros.h"
#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
#include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h"
#include "sandbox/linux/bpf_dsl/policy.h"
#include "sandbox/linux/seccomp-bpf/codegen.h"
#include "sandbox/linux/seccomp-bpf/die.h"
#include "sandbox/linux/seccomp-bpf/errorcode.h"
#include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
#include "sandbox/linux/seccomp-bpf/syscall.h"
#include "sandbox/linux/seccomp-bpf/syscall_iterator.h"

namespace sandbox {
namespace bpf_dsl {

namespace {

#if defined(__i386__) || defined(__x86_64__)
const bool kIsIntel = true;
#else
const bool kIsIntel = false;
#endif
#if defined(__x86_64__) && defined(__ILP32__)
const bool kIsX32 = true;
#else
const bool kIsX32 = false;
#endif

const int kSyscallsRequiredForUnsafeTraps[] = {
    __NR_rt_sigprocmask,
    __NR_rt_sigreturn,
#if defined(__NR_sigprocmask)
    __NR_sigprocmask,
#endif
#if defined(__NR_sigreturn)
    __NR_sigreturn,
#endif
};

bool HasExactlyOneBit(uint64_t x) {
  // Common trick; e.g., see http://stackoverflow.com/a/108329.
  return x != 0 && (x & (x - 1)) == 0;
}

// A Trap() handler that returns an "errno" value. The value is encoded
// in the "aux" parameter.
intptr_t ReturnErrno(const struct arch_seccomp_data&, void* aux) {
  // TrapFnc functions report error by following the native kernel convention
  // of returning an exit code in the range of -1..-4096. They do not try to
  // set errno themselves. The glibc wrapper that triggered the SIGSYS will
  // ultimately do so for us.
  int err = reinterpret_cast<intptr_t>(aux) & SECCOMP_RET_DATA;
  return -err;
}

bool HasUnsafeTraps(const Policy* policy) {
  DCHECK(policy);
  for (uint32_t sysnum : SyscallSet::ValidOnly()) {
    if (policy->EvaluateSyscall(sysnum)->HasUnsafeTraps()) {
      return true;
    }
  }
  return policy->InvalidSyscall()->HasUnsafeTraps();
}

}  // namespace

struct PolicyCompiler::Range {
  uint32_t from;
  CodeGen::Node node;
};

PolicyCompiler::PolicyCompiler(const Policy* policy, TrapRegistry* registry)
    : policy_(policy),
      registry_(registry),
      conds_(),
      gen_(),
      has_unsafe_traps_(HasUnsafeTraps(policy_)) {
  DCHECK(policy);
}

PolicyCompiler::~PolicyCompiler() {
}

scoped_ptr<CodeGen::Program> PolicyCompiler::Compile() {
  if (!policy_->InvalidSyscall()->IsDeny()) {
    SANDBOX_DIE("Policies should deny invalid system calls.");
  }

  // If our BPF program has unsafe traps, enable support for them.
  if (has_unsafe_traps_) {
    // As support for unsafe jumps essentially defeats all the security
    // measures that the sandbox provides, we print a big warning message --
    // and of course, we make sure to only ever enable this feature if it
    // is actually requested by the sandbox policy.
    if (Syscall::Call(-1) == -1 && errno == ENOSYS) {
      SANDBOX_DIE(
          "Support for UnsafeTrap() has not yet been ported to this "
          "architecture");
    }

    for (int sysnum : kSyscallsRequiredForUnsafeTraps) {
      if (!policy_->EvaluateSyscall(sysnum)->IsAllow()) {
        SANDBOX_DIE(
            "Policies that use UnsafeTrap() must unconditionally allow all "
            "required system calls");
      }
    }

    if (!registry_->EnableUnsafeTraps()) {
      // We should never be able to get here, as UnsafeTrap() should never
      // actually return a valid ErrorCode object unless the user set the
      // CHROME_SANDBOX_DEBUGGING environment variable; and therefore,
      // "has_unsafe_traps" would always be false. But better double-check
      // than enabling dangerous code.
      SANDBOX_DIE("We'd rather die than enable unsafe traps");
    }
  }

  // Assemble the BPF filter program.
  scoped_ptr<CodeGen::Program> program(new CodeGen::Program());
  gen_.Compile(AssemblePolicy(), program.get());
  return program.Pass();
}

CodeGen::Node PolicyCompiler::AssemblePolicy() {
  // A compiled policy consists of three logical parts:
  //   1. Check that the "arch" field matches the expected architecture.
  //   2. If the policy involves unsafe traps, check if the syscall was
  //      invoked by Syscall::Call, and then allow it unconditionally.
  //   3. Check the system call number and jump to the appropriate compiled
  //      system call policy number.
  return CheckArch(MaybeAddEscapeHatch(DispatchSyscall()));
}

CodeGen::Node PolicyCompiler::CheckArch(CodeGen::Node passed) {
  // If the architecture doesn't match SECCOMP_ARCH, disallow the
  // system call.
  return gen_.MakeInstruction(
      BPF_LD + BPF_W + BPF_ABS, SECCOMP_ARCH_IDX,
      gen_.MakeInstruction(
          BPF_JMP + BPF_JEQ + BPF_K, SECCOMP_ARCH, passed,
          CompileResult(Kill("Invalid audit architecture in BPF filter"))));
}

CodeGen::Node PolicyCompiler::MaybeAddEscapeHatch(CodeGen::Node rest) {
  // If no unsafe traps, then simply return |rest|.
  if (!has_unsafe_traps_) {
    return rest;
  }

  // Allow system calls, if they originate from our magic return address
  // (which we can query by calling Syscall::Call(-1)).
  uint64_t syscall_entry_point =
      static_cast<uint64_t>(static_cast<uintptr_t>(Syscall::Call(-1)));
  uint32_t low = static_cast<uint32_t>(syscall_entry_point);
  uint32_t hi = static_cast<uint32_t>(syscall_entry_point >> 32);

  // BPF cannot do native 64-bit comparisons, so we have to compare
  // both 32-bit halves of the instruction pointer. If they match what
  // we expect, we return ERR_ALLOWED. If either or both don't match,
  // we continue evalutating the rest of the sandbox policy.
  //
  // For simplicity, we check the full 64-bit instruction pointer even
  // on 32-bit architectures.
  return gen_.MakeInstruction(
      BPF_LD + BPF_W + BPF_ABS, SECCOMP_IP_LSB_IDX,
      gen_.MakeInstruction(
          BPF_JMP + BPF_JEQ + BPF_K, low,
          gen_.MakeInstruction(
              BPF_LD + BPF_W + BPF_ABS, SECCOMP_IP_MSB_IDX,
              gen_.MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, hi,
                                   CompileResult(Allow()), rest)),
          rest));
}

CodeGen::Node PolicyCompiler::DispatchSyscall() {
  // Evaluate all possible system calls and group their ErrorCodes into
  // ranges of identical codes.
  Ranges ranges;
  FindRanges(&ranges);

  // Compile the system call ranges to an optimized BPF jumptable
  CodeGen::Node jumptable = AssembleJumpTable(ranges.begin(), ranges.end());

  // Grab the system call number, so that we can check it and then
  // execute the jump table.
  return gen_.MakeInstruction(
      BPF_LD + BPF_W + BPF_ABS, SECCOMP_NR_IDX, CheckSyscallNumber(jumptable));
}

CodeGen::Node PolicyCompiler::CheckSyscallNumber(CodeGen::Node passed) {
  if (kIsIntel) {
    // On Intel architectures, verify that system call numbers are in the
    // expected number range.
    CodeGen::Node invalidX32 =
        CompileResult(Kill("Illegal mixing of system call ABIs"));
    if (kIsX32) {
      // The newer x32 API always sets bit 30.
      return gen_.MakeInstruction(
          BPF_JMP + BPF_JSET + BPF_K, 0x40000000, passed, invalidX32);
    } else {
      // The older i386 and x86-64 APIs clear bit 30 on all system calls.
      return gen_.MakeInstruction(
          BPF_JMP + BPF_JSET + BPF_K, 0x40000000, invalidX32, passed);
    }
  }

  // TODO(mdempsky): Similar validation for other architectures?
  return passed;
}

void PolicyCompiler::FindRanges(Ranges* ranges) {
  // Please note that "struct seccomp_data" defines system calls as a signed
  // int32_t, but BPF instructions always operate on unsigned quantities. We
  // deal with this disparity by enumerating from MIN_SYSCALL to MAX_SYSCALL,
  // and then verifying that the rest of the number range (both positive and
  // negative) all return the same ErrorCode.
  const CodeGen::Node invalid_node = CompileResult(policy_->InvalidSyscall());
  uint32_t old_sysnum = 0;
  CodeGen::Node old_node =
      SyscallSet::IsValid(old_sysnum)
          ? CompileResult(policy_->EvaluateSyscall(old_sysnum))
          : invalid_node;

  for (uint32_t sysnum : SyscallSet::All()) {
    CodeGen::Node node =
        SyscallSet::IsValid(sysnum)
            ? CompileResult(policy_->EvaluateSyscall(static_cast<int>(sysnum)))
            : invalid_node;
    // N.B., here we rely on CodeGen folding (i.e., returning the same
    // node value for) identical code sequences, otherwise our jump
    // table will blow up in size.
    if (node != old_node) {
      ranges->push_back(Range{old_sysnum, old_node});
      old_sysnum = sysnum;
      old_node = node;
    }
  }
  ranges->push_back(Range{old_sysnum, old_node});
}

CodeGen::Node PolicyCompiler::AssembleJumpTable(Ranges::const_iterator start,
                                                Ranges::const_iterator stop) {
  // We convert the list of system call ranges into jump table that performs
  // a binary search over the ranges.
  // As a sanity check, we need to have at least one distinct ranges for us
  // to be able to build a jump table.
  if (stop - start <= 0) {
    SANDBOX_DIE("Invalid set of system call ranges");
  } else if (stop - start == 1) {
    // If we have narrowed things down to a single range object, we can
    // return from the BPF filter program.
    return start->node;
  }

  // Pick the range object that is located at the mid point of our list.
  // We compare our system call number against the lowest valid system call
  // number in this range object. If our number is lower, it is outside of
  // this range object. If it is greater or equal, it might be inside.
  Ranges::const_iterator mid = start + (stop - start) / 2;

  // Sub-divide the list of ranges and continue recursively.
  CodeGen::Node jf = AssembleJumpTable(start, mid);
  CodeGen::Node jt = AssembleJumpTable(mid, stop);
  return gen_.MakeInstruction(BPF_JMP + BPF_JGE + BPF_K, mid->from, jt, jf);
}

CodeGen::Node PolicyCompiler::CompileResult(const ResultExpr& res) {
  return RetExpression(res->Compile(this));
}

CodeGen::Node PolicyCompiler::RetExpression(const ErrorCode& err) {
  switch (err.error_type()) {
    case ErrorCode::ET_COND:
      return CondExpression(err);
    case ErrorCode::ET_SIMPLE:
    case ErrorCode::ET_TRAP:
      return gen_.MakeInstruction(BPF_RET + BPF_K, err.err());
    default:
      SANDBOX_DIE("ErrorCode is not suitable for returning from a BPF program");
  }
}

CodeGen::Node PolicyCompiler::CondExpression(const ErrorCode& cond) {
  // Sanity check that |cond| makes sense.
  if (cond.argno_ < 0 || cond.argno_ >= 6) {
    SANDBOX_DIE("sandbox_bpf: invalid argument number");
  }
  if (cond.width_ != ErrorCode::TP_32BIT &&
      cond.width_ != ErrorCode::TP_64BIT) {
    SANDBOX_DIE("sandbox_bpf: invalid argument width");
  }
  if (cond.mask_ == 0) {
    SANDBOX_DIE("sandbox_bpf: zero mask is invalid");
  }
  if ((cond.value_ & cond.mask_) != cond.value_) {
    SANDBOX_DIE("sandbox_bpf: value contains masked out bits");
  }
  if (cond.width_ == ErrorCode::TP_32BIT &&
      ((cond.mask_ >> 32) != 0 || (cond.value_ >> 32) != 0)) {
    SANDBOX_DIE("sandbox_bpf: test exceeds argument size");
  }
  // TODO(mdempsky): Reject TP_64BIT on 32-bit platforms. For now we allow it
  // because some SandboxBPF unit tests exercise it.

  CodeGen::Node passed = RetExpression(*cond.passed_);
  CodeGen::Node failed = RetExpression(*cond.failed_);

  // We want to emit code to check "(arg & mask) == value" where arg, mask, and
  // value are 64-bit values, but the BPF machine is only 32-bit. We implement
  // this by independently testing the upper and lower 32-bits and continuing to
  // |passed| if both evaluate true, or to |failed| if either evaluate false.
  return CondExpressionHalf(cond,
                            UpperHalf,
                            CondExpressionHalf(cond, LowerHalf, passed, failed),
                            failed);
}

CodeGen::Node PolicyCompiler::CondExpressionHalf(const ErrorCode& cond,
                                                 ArgHalf half,
                                                 CodeGen::Node passed,
                                                 CodeGen::Node failed) {
  if (cond.width_ == ErrorCode::TP_32BIT && half == UpperHalf) {
    // Special logic for sanity checking the upper 32-bits of 32-bit system
    // call arguments.

    // TODO(mdempsky): Compile Unexpected64bitArgument() just per program.
    CodeGen::Node invalid_64bit = RetExpression(Unexpected64bitArgument());

    const uint32_t upper = SECCOMP_ARG_MSB_IDX(cond.argno_);
    const uint32_t lower = SECCOMP_ARG_LSB_IDX(cond.argno_);

    if (sizeof(void*) == 4) {
      // On 32-bit platforms, the upper 32-bits should always be 0:
      //   LDW  [upper]
      //   JEQ  0, passed, invalid
      return gen_.MakeInstruction(
          BPF_LD + BPF_W + BPF_ABS,
          upper,
          gen_.MakeInstruction(
              BPF_JMP + BPF_JEQ + BPF_K, 0, passed, invalid_64bit));
    }

    // On 64-bit platforms, the upper 32-bits may be 0 or ~0; but we only allow
    // ~0 if the sign bit of the lower 32-bits is set too:
    //   LDW  [upper]
    //   JEQ  0, passed, (next)
    //   JEQ  ~0, (next), invalid
    //   LDW  [lower]
    //   JSET (1<<31), passed, invalid
    //
    // TODO(mdempsky): The JSET instruction could perhaps jump to passed->next
    // instead, as the first instruction of passed should be "LDW [lower]".
    return gen_.MakeInstruction(
        BPF_LD + BPF_W + BPF_ABS,
        upper,
        gen_.MakeInstruction(
            BPF_JMP + BPF_JEQ + BPF_K,
            0,
            passed,
            gen_.MakeInstruction(
                BPF_JMP + BPF_JEQ + BPF_K,
                std::numeric_limits<uint32_t>::max(),
                gen_.MakeInstruction(
                    BPF_LD + BPF_W + BPF_ABS,
                    lower,
                    gen_.MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
                                         1U << 31,
                                         passed,
                                         invalid_64bit)),
                invalid_64bit)));
  }

  const uint32_t idx = (half == UpperHalf) ? SECCOMP_ARG_MSB_IDX(cond.argno_)
                                           : SECCOMP_ARG_LSB_IDX(cond.argno_);
  const uint32_t mask = (half == UpperHalf) ? cond.mask_ >> 32 : cond.mask_;
  const uint32_t value = (half == UpperHalf) ? cond.value_ >> 32 : cond.value_;

  // Emit a suitable instruction sequence for (arg & mask) == value.

  // For (arg & 0) == 0, just return passed.
  if (mask == 0) {
    CHECK_EQ(0U, value);
    return passed;
  }

  // For (arg & ~0) == value, emit:
  //   LDW  [idx]
  //   JEQ  value, passed, failed
  if (mask == std::numeric_limits<uint32_t>::max()) {
    return gen_.MakeInstruction(
        BPF_LD + BPF_W + BPF_ABS,
        idx,
        gen_.MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed));
  }

  // For (arg & mask) == 0, emit:
  //   LDW  [idx]
  //   JSET mask, failed, passed
  // (Note: failed and passed are intentionally swapped.)
  if (value == 0) {
    return gen_.MakeInstruction(
        BPF_LD + BPF_W + BPF_ABS,
        idx,
        gen_.MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, mask, failed, passed));
  }

  // For (arg & x) == x where x is a single-bit value, emit:
  //   LDW  [idx]
  //   JSET mask, passed, failed
  if (mask == value && HasExactlyOneBit(mask)) {
    return gen_.MakeInstruction(
        BPF_LD + BPF_W + BPF_ABS,
        idx,
        gen_.MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, mask, passed, failed));
  }

  // Generic fallback:
  //   LDW  [idx]
  //   AND  mask
  //   JEQ  value, passed, failed
  return gen_.MakeInstruction(
      BPF_LD + BPF_W + BPF_ABS,
      idx,
      gen_.MakeInstruction(
          BPF_ALU + BPF_AND + BPF_K,
          mask,
          gen_.MakeInstruction(
              BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed)));
}

ErrorCode PolicyCompiler::Unexpected64bitArgument() {
  return Kill("Unexpected 64bit argument detected")->Compile(this);
}

ErrorCode PolicyCompiler::Error(int err) {
  if (has_unsafe_traps_) {
    // When inside an UnsafeTrap() callback, we want to allow all system calls.
    // This means, we must conditionally disable the sandbox -- and that's not
    // something that kernel-side BPF filters can do, as they cannot inspect
    // any state other than the syscall arguments.
    // But if we redirect all error handlers to user-space, then we can easily
    // make this decision.
    // The performance penalty for this extra round-trip to user-space is not
    // actually that bad, as we only ever pay it for denied system calls; and a
    // typical program has very few of these.
    return Trap(ReturnErrno, reinterpret_cast<void*>(err), true);
  }

  return ErrorCode(err);
}

ErrorCode PolicyCompiler::Trap(TrapRegistry::TrapFnc fnc,
                               const void* aux,
                               bool safe) {
  uint16_t trap_id = registry_->Add(fnc, aux, safe);
  return ErrorCode(trap_id, fnc, aux, safe);
}

bool PolicyCompiler::IsRequiredForUnsafeTrap(int sysno) {
  for (size_t i = 0; i < arraysize(kSyscallsRequiredForUnsafeTraps); ++i) {
    if (sysno == kSyscallsRequiredForUnsafeTraps[i]) {
      return true;
    }
  }
  return false;
}

ErrorCode PolicyCompiler::CondMaskedEqual(int argno,
                                          ErrorCode::ArgType width,
                                          uint64_t mask,
                                          uint64_t value,
                                          const ErrorCode& passed,
                                          const ErrorCode& failed) {
  return ErrorCode(argno,
                   width,
                   mask,
                   value,
                   &*conds_.insert(passed).first,
                   &*conds_.insert(failed).first);
}

}  // namespace bpf_dsl
}  // namespace sandbox
