// 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/verifier.h"

#include <string.h>

#include <limits>

#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/bpf_dsl/policy_compiler.h"
#include "sandbox/linux/bpf_dsl/seccomp_macros.h"
#include "sandbox/linux/bpf_dsl/syscall_set.h"
#include "sandbox/linux/seccomp-bpf/errorcode.h"
#include "sandbox/linux/system_headers/linux_seccomp.h"

namespace sandbox {
namespace bpf_dsl {

namespace {

const uint64_t kLower32Bits = std::numeric_limits<uint32_t>::max();
const uint64_t kUpper32Bits = static_cast<uint64_t>(kLower32Bits) << 32;

struct State {
  State(const std::vector<struct sock_filter>& p,
        const struct arch_seccomp_data& d)
      : program(p), data(d), ip(0), accumulator(0), acc_is_valid(false) {}
  const std::vector<struct sock_filter>& program;
  const struct arch_seccomp_data& data;
  unsigned int ip;
  uint32_t accumulator;
  bool acc_is_valid;

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(State);
};

uint32_t EvaluateErrorCode(bpf_dsl::PolicyCompiler* compiler,
                           const ErrorCode& code,
                           const struct arch_seccomp_data& data) {
  if (code.error_type() == ErrorCode::ET_SIMPLE ||
      code.error_type() == ErrorCode::ET_TRAP) {
    return code.err();
  } else if (code.error_type() == ErrorCode::ET_COND) {
    if (code.width() == ErrorCode::TP_32BIT &&
        (data.args[code.argno()] >> 32) &&
        (data.args[code.argno()] & 0xFFFFFFFF80000000ull) !=
            0xFFFFFFFF80000000ull) {
      return compiler->Unexpected64bitArgument().err();
    }
    bool equal = (data.args[code.argno()] & code.mask()) == code.value();
    return EvaluateErrorCode(compiler, equal ? *code.passed() : *code.failed(),
                             data);
  } else {
    return SECCOMP_RET_INVALID;
  }
}

bool VerifyErrorCode(bpf_dsl::PolicyCompiler* compiler,
                     const std::vector<struct sock_filter>& program,
                     struct arch_seccomp_data* data,
                     const ErrorCode& root_code,
                     const ErrorCode& code,
                     const char** err) {
  if (code.error_type() == ErrorCode::ET_SIMPLE ||
      code.error_type() == ErrorCode::ET_TRAP) {
    const uint32_t computed_ret = Verifier::EvaluateBPF(program, *data, err);
    if (*err) {
      return false;
    }
    const uint32_t policy_ret = EvaluateErrorCode(compiler, root_code, *data);
    if (computed_ret != policy_ret) {
      // For efficiency's sake, we'd much rather compare "computed_ret"
      // against "code.err()". This works most of the time, but it doesn't
      // always work for nested conditional expressions. The test values
      // that we generate on the fly to probe expressions can trigger
      // code flow decisions in multiple nodes of the decision tree, and the
      // only way to compute the correct error code in that situation is by
      // calling EvaluateErrorCode().
      *err = "Exit code from BPF program doesn't match";
      return false;
    }
  } else if (code.error_type() == ErrorCode::ET_COND) {
    if (code.argno() < 0 || code.argno() >= 6) {
      *err = "Invalid argument number in error code";
      return false;
    }

    // TODO(mdempsky): The test values generated here try to provide good
    // coverage for generated BPF instructions while avoiding combinatorial
    // explosion on large policies. Ideally we would instead take a fuzzing-like
    // approach and generate a bounded number of test cases regardless of policy
    // size.

    // Verify that we can check a value for simple equality.
    data->args[code.argno()] = code.value();
    if (!VerifyErrorCode(compiler, program, data, root_code, *code.passed(),
                         err)) {
      return false;
    }

    // If mask ignores any bits, verify that setting those bits is still
    // detected as equality.
    uint64_t ignored_bits = ~code.mask();
    if (code.width() == ErrorCode::TP_32BIT) {
      ignored_bits = static_cast<uint32_t>(ignored_bits);
    }
    if ((ignored_bits & kLower32Bits) != 0) {
      data->args[code.argno()] = code.value() | (ignored_bits & kLower32Bits);
      if (!VerifyErrorCode(compiler, program, data, root_code, *code.passed(),
                           err)) {
        return false;
      }
    }
    if ((ignored_bits & kUpper32Bits) != 0) {
      data->args[code.argno()] = code.value() | (ignored_bits & kUpper32Bits);
      if (!VerifyErrorCode(compiler, program, data, root_code, *code.passed(),
                           err)) {
        return false;
      }
    }

    // Verify that changing bits included in the mask is detected as inequality.
    if ((code.mask() & kLower32Bits) != 0) {
      data->args[code.argno()] = code.value() ^ (code.mask() & kLower32Bits);
      if (!VerifyErrorCode(compiler, program, data, root_code, *code.failed(),
                           err)) {
        return false;
      }
    }
    if ((code.mask() & kUpper32Bits) != 0) {
      data->args[code.argno()] = code.value() ^ (code.mask() & kUpper32Bits);
      if (!VerifyErrorCode(compiler, program, data, root_code, *code.failed(),
                           err)) {
        return false;
      }
    }

    if (code.width() == ErrorCode::TP_32BIT) {
      // For 32-bit system call arguments, we emit additional instructions to
      // validate the upper 32-bits. Here we test that validation.

      // Arbitrary 64-bit values should be rejected.
      data->args[code.argno()] = 1ULL << 32;
      if (!VerifyErrorCode(compiler, program, data, root_code,
                           compiler->Unexpected64bitArgument(), err)) {
        return false;
      }

      // Upper 32-bits set without the MSB of the lower 32-bits set should be
      // rejected too.
      data->args[code.argno()] = kUpper32Bits;
      if (!VerifyErrorCode(compiler, program, data, root_code,
                           compiler->Unexpected64bitArgument(), err)) {
        return false;
      }
    }
  } else {
    *err = "Attempting to return invalid error code from BPF program";
    return false;
  }
  return true;
}

void Ld(State* state, const struct sock_filter& insn, const char** err) {
  if (BPF_SIZE(insn.code) != BPF_W || BPF_MODE(insn.code) != BPF_ABS ||
      insn.jt != 0 || insn.jf != 0) {
    *err = "Invalid BPF_LD instruction";
    return;
  }
  if (insn.k < sizeof(struct arch_seccomp_data) && (insn.k & 3) == 0) {
    // We only allow loading of properly aligned 32bit quantities.
    memcpy(&state->accumulator,
           reinterpret_cast<const char*>(&state->data) + insn.k, 4);
  } else {
    *err = "Invalid operand in BPF_LD instruction";
    return;
  }
  state->acc_is_valid = true;
  return;
}

void Jmp(State* state, const struct sock_filter& insn, const char** err) {
  if (BPF_OP(insn.code) == BPF_JA) {
    if (state->ip + insn.k + 1 >= state->program.size() ||
        state->ip + insn.k + 1 <= state->ip) {
    compilation_failure:
      *err = "Invalid BPF_JMP instruction";
      return;
    }
    state->ip += insn.k;
  } else {
    if (BPF_SRC(insn.code) != BPF_K || !state->acc_is_valid ||
        state->ip + insn.jt + 1 >= state->program.size() ||
        state->ip + insn.jf + 1 >= state->program.size()) {
      goto compilation_failure;
    }
    switch (BPF_OP(insn.code)) {
      case BPF_JEQ:
        if (state->accumulator == insn.k) {
          state->ip += insn.jt;
        } else {
          state->ip += insn.jf;
        }
        break;
      case BPF_JGT:
        if (state->accumulator > insn.k) {
          state->ip += insn.jt;
        } else {
          state->ip += insn.jf;
        }
        break;
      case BPF_JGE:
        if (state->accumulator >= insn.k) {
          state->ip += insn.jt;
        } else {
          state->ip += insn.jf;
        }
        break;
      case BPF_JSET:
        if (state->accumulator & insn.k) {
          state->ip += insn.jt;
        } else {
          state->ip += insn.jf;
        }
        break;
      default:
        goto compilation_failure;
    }
  }
}

uint32_t Ret(State*, const struct sock_filter& insn, const char** err) {
  if (BPF_SRC(insn.code) != BPF_K) {
    *err = "Invalid BPF_RET instruction";
    return 0;
  }
  return insn.k;
}

void Alu(State* state, const struct sock_filter& insn, const char** err) {
  if (BPF_OP(insn.code) == BPF_NEG) {
    state->accumulator = -state->accumulator;
    return;
  } else {
    if (BPF_SRC(insn.code) != BPF_K) {
      *err = "Unexpected source operand in arithmetic operation";
      return;
    }
    switch (BPF_OP(insn.code)) {
      case BPF_ADD:
        state->accumulator += insn.k;
        break;
      case BPF_SUB:
        state->accumulator -= insn.k;
        break;
      case BPF_MUL:
        state->accumulator *= insn.k;
        break;
      case BPF_DIV:
        if (!insn.k) {
          *err = "Illegal division by zero";
          break;
        }
        state->accumulator /= insn.k;
        break;
      case BPF_MOD:
        if (!insn.k) {
          *err = "Illegal division by zero";
          break;
        }
        state->accumulator %= insn.k;
        break;
      case BPF_OR:
        state->accumulator |= insn.k;
        break;
      case BPF_XOR:
        state->accumulator ^= insn.k;
        break;
      case BPF_AND:
        state->accumulator &= insn.k;
        break;
      case BPF_LSH:
        if (insn.k > 32) {
          *err = "Illegal shift operation";
          break;
        }
        state->accumulator <<= insn.k;
        break;
      case BPF_RSH:
        if (insn.k > 32) {
          *err = "Illegal shift operation";
          break;
        }
        state->accumulator >>= insn.k;
        break;
      default:
        *err = "Invalid operator in arithmetic operation";
        break;
    }
  }
}

}  // namespace

bool Verifier::VerifyBPF(bpf_dsl::PolicyCompiler* compiler,
                         const std::vector<struct sock_filter>& program,
                         const bpf_dsl::Policy& policy,
                         const char** err) {
  *err = NULL;
  for (uint32_t sysnum : SyscallSet::All()) {
    // We ideally want to iterate over the full system call range and values
    // just above and just below this range. This gives us the full result set
    // of the "evaluators".
    // On Intel systems, this can fail in a surprising way, as a cleared bit 30
    // indicates either i386 or x86-64; and a set bit 30 indicates x32. And
    // unless we pay attention to setting this bit correctly, an early check in
    // our BPF program will make us fail with a misleading error code.
    struct arch_seccomp_data data = {static_cast<int>(sysnum),
                                     static_cast<uint32_t>(SECCOMP_ARCH)};
#if defined(__i386__) || defined(__x86_64__)
#if defined(__x86_64__) && defined(__ILP32__)
    if (!(sysnum & 0x40000000u)) {
      continue;
    }
#else
    if (sysnum & 0x40000000u) {
      continue;
    }
#endif
#endif
    ErrorCode code = SyscallSet::IsValid(sysnum)
                         ? policy.EvaluateSyscall(sysnum)->Compile(compiler)
                         : policy.InvalidSyscall()->Compile(compiler);
    if (!VerifyErrorCode(compiler, program, &data, code, code, err)) {
      return false;
    }
  }
  return true;
}

uint32_t Verifier::EvaluateBPF(const std::vector<struct sock_filter>& program,
                               const struct arch_seccomp_data& data,
                               const char** err) {
  *err = NULL;
  if (program.size() < 1 || program.size() >= SECCOMP_MAX_PROGRAM_SIZE) {
    *err = "Invalid program length";
    return 0;
  }
  for (State state(program, data); !*err; ++state.ip) {
    if (state.ip >= program.size()) {
      *err = "Invalid instruction pointer in BPF program";
      break;
    }
    const struct sock_filter& insn = program[state.ip];
    switch (BPF_CLASS(insn.code)) {
      case BPF_LD:
        Ld(&state, insn, err);
        break;
      case BPF_JMP:
        Jmp(&state, insn, err);
        break;
      case BPF_RET: {
        uint32_t r = Ret(&state, insn, err);
        switch (r & SECCOMP_RET_ACTION) {
          case SECCOMP_RET_TRAP:
          case SECCOMP_RET_ERRNO:
          case SECCOMP_RET_TRACE:
          case SECCOMP_RET_ALLOW:
            break;
          case SECCOMP_RET_KILL:     // We don't ever generate this
          case SECCOMP_RET_INVALID:  // Should never show up in BPF program
          default:
            *err = "Unexpected return code found in BPF program";
            return 0;
        }
        return r;
      }
      case BPF_ALU:
        Alu(&state, insn, err);
        break;
      default:
        *err = "Unexpected instruction in BPF program";
        break;
    }
  }
  return 0;
}

}  // namespace bpf_dsl
}  // namespace sandbox
