// Copyright 2014 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/bpf_dsl.h"

#include <limits>

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h"
#include "sandbox/linux/bpf_dsl/errorcode.h"
#include "sandbox/linux/bpf_dsl/policy_compiler.h"

namespace sandbox {
namespace bpf_dsl {
namespace {

class AllowResultExprImpl : public internal::ResultExprImpl {
 public:
  AllowResultExprImpl() {}

  ErrorCode Compile(PolicyCompiler* pc) const override {
    return ErrorCode(ErrorCode::ERR_ALLOWED);
  }

  bool IsAllow() const override { return true; }

 private:
  ~AllowResultExprImpl() override {}

  DISALLOW_COPY_AND_ASSIGN(AllowResultExprImpl);
};

class ErrorResultExprImpl : public internal::ResultExprImpl {
 public:
  explicit ErrorResultExprImpl(int err) : err_(err) {
    CHECK(err_ >= ErrorCode::ERR_MIN_ERRNO && err_ <= ErrorCode::ERR_MAX_ERRNO);
  }

  ErrorCode Compile(PolicyCompiler* pc) const override {
    return pc->Error(err_);
  }

  bool IsDeny() const override { return true; }

 private:
  ~ErrorResultExprImpl() override {}

  int err_;

  DISALLOW_COPY_AND_ASSIGN(ErrorResultExprImpl);
};

class KillResultExprImpl : public internal::ResultExprImpl {
 public:
  KillResultExprImpl() {}

  ErrorCode Compile(PolicyCompiler* pc) const override {
    return ErrorCode(ErrorCode::ERR_KILL);
  }

  bool IsDeny() const override { return true; }

 private:
  ~KillResultExprImpl() override {}

  DISALLOW_COPY_AND_ASSIGN(KillResultExprImpl);
};

class TraceResultExprImpl : public internal::ResultExprImpl {
 public:
  TraceResultExprImpl(uint16_t aux) : aux_(aux) {}

  ErrorCode Compile(PolicyCompiler* pc) const override {
    return ErrorCode(ErrorCode::ERR_TRACE + aux_);
  }

 private:
  ~TraceResultExprImpl() override {}

  uint16_t aux_;

  DISALLOW_COPY_AND_ASSIGN(TraceResultExprImpl);
};

class TrapResultExprImpl : public internal::ResultExprImpl {
 public:
  TrapResultExprImpl(TrapRegistry::TrapFnc func, const void* arg, bool safe)
      : func_(func), arg_(arg), safe_(safe) {
    DCHECK(func_);
  }

  ErrorCode Compile(PolicyCompiler* pc) const override {
    return pc->Trap(func_, arg_, safe_);
  }

  bool HasUnsafeTraps() const override { return safe_ == false; }

  bool IsDeny() const override { return true; }

 private:
  ~TrapResultExprImpl() override {}

  TrapRegistry::TrapFnc func_;
  const void* arg_;
  bool safe_;

  DISALLOW_COPY_AND_ASSIGN(TrapResultExprImpl);
};

class IfThenResultExprImpl : public internal::ResultExprImpl {
 public:
  IfThenResultExprImpl(const BoolExpr& cond,
                       const ResultExpr& then_result,
                       const ResultExpr& else_result)
      : cond_(cond), then_result_(then_result), else_result_(else_result) {}

  ErrorCode Compile(PolicyCompiler* pc) const override {
    return cond_->Compile(
        pc, then_result_->Compile(pc), else_result_->Compile(pc));
  }

  bool HasUnsafeTraps() const override {
    return then_result_->HasUnsafeTraps() || else_result_->HasUnsafeTraps();
  }

 private:
  ~IfThenResultExprImpl() override {}

  BoolExpr cond_;
  ResultExpr then_result_;
  ResultExpr else_result_;

  DISALLOW_COPY_AND_ASSIGN(IfThenResultExprImpl);
};

class ConstBoolExprImpl : public internal::BoolExprImpl {
 public:
  ConstBoolExprImpl(bool value) : value_(value) {}

  ErrorCode Compile(PolicyCompiler* pc,
                    ErrorCode true_ec,
                    ErrorCode false_ec) const override {
    return value_ ? true_ec : false_ec;
  }

 private:
  ~ConstBoolExprImpl() override {}

  bool value_;

  DISALLOW_COPY_AND_ASSIGN(ConstBoolExprImpl);
};

class PrimitiveBoolExprImpl : public internal::BoolExprImpl {
 public:
  PrimitiveBoolExprImpl(int argno,
                        ErrorCode::ArgType is_32bit,
                        uint64_t mask,
                        uint64_t value)
      : argno_(argno), is_32bit_(is_32bit), mask_(mask), value_(value) {}

  ErrorCode Compile(PolicyCompiler* pc,
                    ErrorCode true_ec,
                    ErrorCode false_ec) const override {
    return pc->CondMaskedEqual(
        argno_, is_32bit_, mask_, value_, true_ec, false_ec);
  }

 private:
  ~PrimitiveBoolExprImpl() override {}

  int argno_;
  ErrorCode::ArgType is_32bit_;
  uint64_t mask_;
  uint64_t value_;

  DISALLOW_COPY_AND_ASSIGN(PrimitiveBoolExprImpl);
};

class NegateBoolExprImpl : public internal::BoolExprImpl {
 public:
  explicit NegateBoolExprImpl(const BoolExpr& cond) : cond_(cond) {}

  ErrorCode Compile(PolicyCompiler* pc,
                    ErrorCode true_ec,
                    ErrorCode false_ec) const override {
    return cond_->Compile(pc, false_ec, true_ec);
  }

 private:
  ~NegateBoolExprImpl() override {}

  BoolExpr cond_;

  DISALLOW_COPY_AND_ASSIGN(NegateBoolExprImpl);
};

class AndBoolExprImpl : public internal::BoolExprImpl {
 public:
  AndBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
      : lhs_(lhs), rhs_(rhs) {}

  ErrorCode Compile(PolicyCompiler* pc,
                    ErrorCode true_ec,
                    ErrorCode false_ec) const override {
    return lhs_->Compile(pc, rhs_->Compile(pc, true_ec, false_ec), false_ec);
  }

 private:
  ~AndBoolExprImpl() override {}

  BoolExpr lhs_;
  BoolExpr rhs_;

  DISALLOW_COPY_AND_ASSIGN(AndBoolExprImpl);
};

class OrBoolExprImpl : public internal::BoolExprImpl {
 public:
  OrBoolExprImpl(const BoolExpr& lhs, const BoolExpr& rhs)
      : lhs_(lhs), rhs_(rhs) {}

  ErrorCode Compile(PolicyCompiler* pc,
                    ErrorCode true_ec,
                    ErrorCode false_ec) const override {
    return lhs_->Compile(pc, true_ec, rhs_->Compile(pc, true_ec, false_ec));
  }

 private:
  ~OrBoolExprImpl() override {}

  BoolExpr lhs_;
  BoolExpr rhs_;

  DISALLOW_COPY_AND_ASSIGN(OrBoolExprImpl);
};

}  // namespace

namespace internal {

bool ResultExprImpl::HasUnsafeTraps() const {
  return false;
}

bool ResultExprImpl::IsAllow() const {
  return false;
}

bool ResultExprImpl::IsDeny() const {
  return false;
}

uint64_t DefaultMask(size_t size) {
  switch (size) {
    case 4:
      return std::numeric_limits<uint32_t>::max();
    case 8:
      return std::numeric_limits<uint64_t>::max();
    default:
      CHECK(false) << "Unimplemented DefaultMask case";
      return 0;
  }
}

BoolExpr ArgEq(int num, size_t size, uint64_t mask, uint64_t val) {
  // If this is changed, update Arg<T>::EqualTo's static_cast rules
  // accordingly.
  CHECK(size == 4 || size == 8);

  // TODO(mdempsky): Should we just always use TP_64BIT?
  const ErrorCode::ArgType arg_type =
      (size == 4) ? ErrorCode::TP_32BIT : ErrorCode::TP_64BIT;

  return BoolExpr(new const PrimitiveBoolExprImpl(num, arg_type, mask, val));
}

}  // namespace internal

ResultExpr Allow() {
  return ResultExpr(new const AllowResultExprImpl());
}

ResultExpr Error(int err) {
  return ResultExpr(new const ErrorResultExprImpl(err));
}

ResultExpr Kill() {
  return ResultExpr(new const KillResultExprImpl());
}

ResultExpr Trace(uint16_t aux) {
  return ResultExpr(new const TraceResultExprImpl(aux));
}

ResultExpr Trap(TrapRegistry::TrapFnc trap_func, const void* aux) {
  return ResultExpr(
      new const TrapResultExprImpl(trap_func, aux, true /* safe */));
}

ResultExpr UnsafeTrap(TrapRegistry::TrapFnc trap_func, const void* aux) {
  return ResultExpr(
      new const TrapResultExprImpl(trap_func, aux, false /* unsafe */));
}

BoolExpr BoolConst(bool value) {
  return BoolExpr(new const ConstBoolExprImpl(value));
}

BoolExpr operator!(const BoolExpr& cond) {
  return BoolExpr(new const NegateBoolExprImpl(cond));
}

BoolExpr operator&&(const BoolExpr& lhs, const BoolExpr& rhs) {
  return BoolExpr(new const AndBoolExprImpl(lhs, rhs));
}

BoolExpr operator||(const BoolExpr& lhs, const BoolExpr& rhs) {
  return BoolExpr(new const OrBoolExprImpl(lhs, rhs));
}

Elser If(const BoolExpr& cond, const ResultExpr& then_result) {
  return Elser(nullptr).ElseIf(cond, then_result);
}

Elser::Elser(cons::List<Clause> clause_list) : clause_list_(clause_list) {
}

Elser::Elser(const Elser& elser) : clause_list_(elser.clause_list_) {
}

Elser::~Elser() {
}

Elser Elser::ElseIf(const BoolExpr& cond, const ResultExpr& then_result) const {
  return Elser(Cons(std::make_pair(cond, then_result), clause_list_));
}

ResultExpr Elser::Else(const ResultExpr& else_result) const {
  // We finally have the default result expression for this
  // if/then/else sequence.  Also, we've already accumulated all
  // if/then pairs into a list of reverse order (i.e., lower priority
  // conditions are listed before higher priority ones).  E.g., an
  // expression like
  //
  //    If(b1, e1).ElseIf(b2, e2).ElseIf(b3, e3).Else(e4)
  //
  // will have built up a list like
  //
  //    [(b3, e3), (b2, e2), (b1, e1)].
  //
  // Now that we have e4, we can walk the list and create a ResultExpr
  // tree like:
  //
  //    expr = e4
  //    expr = (b3 ? e3 : expr) = (b3 ? e3 : e4)
  //    expr = (b2 ? e2 : expr) = (b2 ? e2 : (b3 ? e3 : e4))
  //    expr = (b1 ? e1 : expr) = (b1 ? e1 : (b2 ? e2 : (b3 ? e3 : e4)))
  //
  // and end up with an appropriately chained tree.

  ResultExpr expr = else_result;
  for (const Clause& clause : clause_list_) {
    expr = ResultExpr(
        new const IfThenResultExprImpl(clause.first, clause.second, expr));
  }
  return expr;
}

}  // namespace bpf_dsl
}  // namespace sandbox

template class scoped_refptr<const sandbox::bpf_dsl::internal::BoolExprImpl>;
template class scoped_refptr<const sandbox::bpf_dsl::internal::ResultExprImpl>;
