// 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 <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/utsname.h>
#include <unistd.h>

#include <map>
#include <utility>

#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "sandbox/linux/bpf_dsl/bpf_dsl_impl.h"
#include "sandbox/linux/bpf_dsl/codegen.h"
#include "sandbox/linux/bpf_dsl/dump_bpf.h"
#include "sandbox/linux/bpf_dsl/golden/golden_files.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/test_trap_registry.h"
#include "sandbox/linux/bpf_dsl/verifier.h"
#include "sandbox/linux/system_headers/linux_filter.h"
#include "testing/gtest/include/gtest/gtest.h"

#define CASES SANDBOX_BPF_DSL_CASES

namespace sandbox {
namespace bpf_dsl {
namespace {

// Helper function to construct fake arch_seccomp_data objects.
struct arch_seccomp_data FakeSyscall(int nr,
                                     uintptr_t p0 = 0,
                                     uintptr_t p1 = 0,
                                     uintptr_t p2 = 0,
                                     uintptr_t p3 = 0,
                                     uintptr_t p4 = 0,
                                     uintptr_t p5 = 0) {
  // Made up program counter for syscall address.
  const uint64_t kFakePC = 0x543210;

  struct arch_seccomp_data data = {
      nr,
      SECCOMP_ARCH,
      kFakePC,
      {
       p0, p1, p2, p3, p4, p5,
      },
  };

  return data;
}

class PolicyEmulator {
 public:
  PolicyEmulator(const golden::Golden& golden, const Policy& policy)
      : program_() {
    TestTrapRegistry traps;
    program_ = PolicyCompiler(&policy, &traps).Compile();

    // TODO(mdempsky): Generalize to more arches.
    const char* expected = nullptr;
#if defined(ARCH_CPU_X86)
    expected = golden.i386_dump;
#elif defined(ARCH_CPU_X86_64)
    expected = golden.x86_64_dump;
#endif

    if (expected != nullptr) {
      const std::string actual = DumpBPF::StringPrintProgram(program_);
      EXPECT_EQ(expected, actual);
    } else {
      LOG(WARNING) << "Missing golden file data entry";
    }
  }

  ~PolicyEmulator() {}

  void ExpectAllow(const struct arch_seccomp_data& data) const {
    EXPECT_EQ(SECCOMP_RET_ALLOW, Emulate(data));
  }

  void ExpectErrno(uint16_t err, const struct arch_seccomp_data& data) const {
    EXPECT_EQ(SECCOMP_RET_ERRNO | err, Emulate(data));
  }

  void ExpectKill(const struct arch_seccomp_data& data) const {
    EXPECT_EQ(SECCOMP_RET_KILL, Emulate(data));
  }

 private:
  uint32_t Emulate(const struct arch_seccomp_data& data) const {
    const char* err = nullptr;
    uint32_t res = Verifier::EvaluateBPF(program_, data, &err);
    if (err) {
      ADD_FAILURE() << err;
      return 0;
    }
    return res;
  }

  CodeGen::Program program_;

  DISALLOW_COPY_AND_ASSIGN(PolicyEmulator);
};

class BasicPolicy : public Policy {
 public:
  BasicPolicy() {}
  ~BasicPolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_getpgid) {
      const Arg<pid_t> pid(0);
      return If(pid == 0, Error(EPERM)).Else(Error(EINVAL));
    }
    if (sysno == __NR_setuid) {
      const Arg<uid_t> uid(0);
      return If(uid != 42, Kill()).Else(Allow());
    }
    return Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BasicPolicy);
};

TEST(BPFDSL, Basic) {
  PolicyEmulator emulator(golden::kBasicPolicy, BasicPolicy());

  emulator.ExpectErrno(EPERM, FakeSyscall(__NR_getpgid, 0));
  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_getpgid, 1));

  emulator.ExpectAllow(FakeSyscall(__NR_setuid, 42));
  emulator.ExpectKill(FakeSyscall(__NR_setuid, 43));
}

/* On IA-32, socketpair() is implemented via socketcall(). :-( */
#if !defined(ARCH_CPU_X86)
class BooleanLogicPolicy : public Policy {
 public:
  BooleanLogicPolicy() {}
  ~BooleanLogicPolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_socketpair) {
      const Arg<int> domain(0), type(1), protocol(2);
      return If(domain == AF_UNIX &&
                    (type == SOCK_STREAM || type == SOCK_DGRAM) &&
                    protocol == 0,
                Error(EPERM)).Else(Error(EINVAL));
    }
    return Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BooleanLogicPolicy);
};

TEST(BPFDSL, BooleanLogic) {
  PolicyEmulator emulator(golden::kBooleanLogicPolicy, BooleanLogicPolicy());

  const intptr_t kFakeSV = 0x12345;

  // Acceptable combinations that should return EPERM.
  emulator.ExpectErrno(
      EPERM, FakeSyscall(__NR_socketpair, AF_UNIX, SOCK_STREAM, 0, kFakeSV));
  emulator.ExpectErrno(
      EPERM, FakeSyscall(__NR_socketpair, AF_UNIX, SOCK_DGRAM, 0, kFakeSV));

  // Combinations that are invalid for only one reason; should return EINVAL.
  emulator.ExpectErrno(
      EINVAL, FakeSyscall(__NR_socketpair, AF_INET, SOCK_STREAM, 0, kFakeSV));
  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_socketpair, AF_UNIX,
                                           SOCK_SEQPACKET, 0, kFakeSV));
  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_socketpair, AF_UNIX,
                                           SOCK_STREAM, IPPROTO_TCP, kFakeSV));

  // Completely unacceptable combination; should also return EINVAL.
  emulator.ExpectErrno(
      EINVAL, FakeSyscall(__NR_socketpair, AF_INET, SOCK_SEQPACKET, IPPROTO_UDP,
                          kFakeSV));
}
#endif  // !ARCH_CPU_X86

class MoreBooleanLogicPolicy : public Policy {
 public:
  MoreBooleanLogicPolicy() {}
  ~MoreBooleanLogicPolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_setresuid) {
      const Arg<uid_t> ruid(0), euid(1), suid(2);
      return If(ruid == 0 || euid == 0 || suid == 0, Error(EPERM))
          .ElseIf(ruid == 1 && euid == 1 && suid == 1, Error(EAGAIN))
          .Else(Error(EINVAL));
    }
    return Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MoreBooleanLogicPolicy);
};

TEST(BPFDSL, MoreBooleanLogic) {
  PolicyEmulator emulator(golden::kMoreBooleanLogicPolicy,
                          MoreBooleanLogicPolicy());

  // Expect EPERM if any set to 0.
  emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 0, 5, 5));
  emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 5, 0, 5));
  emulator.ExpectErrno(EPERM, FakeSyscall(__NR_setresuid, 5, 5, 0));

  // Expect EAGAIN if all set to 1.
  emulator.ExpectErrno(EAGAIN, FakeSyscall(__NR_setresuid, 1, 1, 1));

  // Expect EINVAL for anything else.
  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 5, 1, 1));
  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 1, 5, 1));
  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 1, 1, 5));
  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setresuid, 3, 4, 5));
}

static const uintptr_t kDeadBeefAddr =
    static_cast<uintptr_t>(0xdeadbeefdeadbeefULL);

class ArgSizePolicy : public Policy {
 public:
  ArgSizePolicy() {}
  ~ArgSizePolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_uname) {
      const Arg<uintptr_t> addr(0);
      return If(addr == kDeadBeefAddr, Error(EPERM)).Else(Allow());
    }
    return Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ArgSizePolicy);
};

TEST(BPFDSL, ArgSizeTest) {
  PolicyEmulator emulator(golden::kArgSizePolicy, ArgSizePolicy());

  emulator.ExpectAllow(FakeSyscall(__NR_uname, 0));
  emulator.ExpectErrno(EPERM, FakeSyscall(__NR_uname, kDeadBeefAddr));
}

class NegativeConstantsPolicy : public Policy {
 public:
  NegativeConstantsPolicy() {}
  ~NegativeConstantsPolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_fcntl) {
      const Arg<int> fd(0);
      return If(fd == -314, Error(EPERM)).Else(Allow());
    }
    return Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(NegativeConstantsPolicy);
};

TEST(BPFDSL, NegativeConstantsTest) {
  PolicyEmulator emulator(golden::kNegativeConstantsPolicy,
                          NegativeConstantsPolicy());

  emulator.ExpectAllow(FakeSyscall(__NR_fcntl, -5, F_DUPFD));
  emulator.ExpectAllow(FakeSyscall(__NR_fcntl, 20, F_DUPFD));
  emulator.ExpectErrno(EPERM, FakeSyscall(__NR_fcntl, -314, F_DUPFD));
}

#if 0
// TODO(mdempsky): This is really an integration test.

class TrappingPolicy : public Policy {
 public:
  TrappingPolicy() {}
  ~TrappingPolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_uname) {
      return Trap(UnameTrap, &count_);
    }
    return Allow();
  }

 private:
  static intptr_t count_;

  static intptr_t UnameTrap(const struct arch_seccomp_data& data, void* aux) {
    BPF_ASSERT_EQ(&count_, aux);
    return ++count_;
  }

  DISALLOW_COPY_AND_ASSIGN(TrappingPolicy);
};

intptr_t TrappingPolicy::count_;

BPF_TEST_C(BPFDSL, TrapTest, TrappingPolicy) {
  ASSERT_SYSCALL_RESULT(1, uname, NULL);
  ASSERT_SYSCALL_RESULT(2, uname, NULL);
  ASSERT_SYSCALL_RESULT(3, uname, NULL);
}
#endif

class MaskingPolicy : public Policy {
 public:
  MaskingPolicy() {}
  ~MaskingPolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_setuid) {
      const Arg<uid_t> uid(0);
      return If((uid & 0xf) == 0, Error(EINVAL)).Else(Error(EACCES));
    }
    if (sysno == __NR_setgid) {
      const Arg<gid_t> gid(0);
      return If((gid & 0xf0) == 0xf0, Error(EINVAL)).Else(Error(EACCES));
    }
    if (sysno == __NR_setpgid) {
      const Arg<pid_t> pid(0);
      return If((pid & 0xa5) == 0xa0, Error(EINVAL)).Else(Error(EACCES));
    }
    return Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MaskingPolicy);
};

TEST(BPFDSL, MaskTest) {
  PolicyEmulator emulator(golden::kMaskingPolicy, MaskingPolicy());

  for (uid_t uid = 0; uid < 0x100; ++uid) {
    const int expect_errno = (uid & 0xf) == 0 ? EINVAL : EACCES;
    emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setuid, uid));
  }

  for (gid_t gid = 0; gid < 0x100; ++gid) {
    const int expect_errno = (gid & 0xf0) == 0xf0 ? EINVAL : EACCES;
    emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setgid, gid));
  }

  for (pid_t pid = 0; pid < 0x100; ++pid) {
    const int expect_errno = (pid & 0xa5) == 0xa0 ? EINVAL : EACCES;
    emulator.ExpectErrno(expect_errno, FakeSyscall(__NR_setpgid, pid, 0));
  }
}

class ElseIfPolicy : public Policy {
 public:
  ElseIfPolicy() {}
  ~ElseIfPolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_setuid) {
      const Arg<uid_t> uid(0);
      return If((uid & 0xfff) == 0, Error(0))
          .ElseIf((uid & 0xff0) == 0, Error(EINVAL))
          .ElseIf((uid & 0xf00) == 0, Error(EEXIST))
          .Else(Error(EACCES));
    }
    return Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ElseIfPolicy);
};

TEST(BPFDSL, ElseIfTest) {
  PolicyEmulator emulator(golden::kElseIfPolicy, ElseIfPolicy());

  emulator.ExpectErrno(0, FakeSyscall(__NR_setuid, 0));

  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setuid, 0x0001));
  emulator.ExpectErrno(EINVAL, FakeSyscall(__NR_setuid, 0x0002));

  emulator.ExpectErrno(EEXIST, FakeSyscall(__NR_setuid, 0x0011));
  emulator.ExpectErrno(EEXIST, FakeSyscall(__NR_setuid, 0x0022));

  emulator.ExpectErrno(EACCES, FakeSyscall(__NR_setuid, 0x0111));
  emulator.ExpectErrno(EACCES, FakeSyscall(__NR_setuid, 0x0222));
}

class SwitchPolicy : public Policy {
 public:
  SwitchPolicy() {}
  ~SwitchPolicy() override {}
  ResultExpr EvaluateSyscall(int sysno) const override {
    if (sysno == __NR_fcntl) {
      const Arg<int> cmd(1);
      const Arg<unsigned long> long_arg(2);
      return Switch(cmd)
          .CASES((F_GETFL, F_GETFD), Error(ENOENT))
          .Case(F_SETFD, If(long_arg == O_CLOEXEC, Allow()).Else(Error(EINVAL)))
          .Case(F_SETFL, Error(EPERM))
          .Default(Error(EACCES));
    }
    return Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(SwitchPolicy);
};

TEST(BPFDSL, SwitchTest) {
  PolicyEmulator emulator(golden::kSwitchPolicy, SwitchPolicy());

  const int kFakeSockFD = 42;

  emulator.ExpectErrno(ENOENT, FakeSyscall(__NR_fcntl, kFakeSockFD, F_GETFD));
  emulator.ExpectErrno(ENOENT, FakeSyscall(__NR_fcntl, kFakeSockFD, F_GETFL));

  emulator.ExpectAllow(
      FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFD, O_CLOEXEC));
  emulator.ExpectErrno(EINVAL,
                       FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFD, 0));

  emulator.ExpectErrno(EPERM,
                       FakeSyscall(__NR_fcntl, kFakeSockFD, F_SETFL, O_RDONLY));

  emulator.ExpectErrno(EACCES,
                       FakeSyscall(__NR_fcntl, kFakeSockFD, F_DUPFD, 0));
}

static intptr_t DummyTrap(const struct arch_seccomp_data& data, void* aux) {
  return 0;
}

TEST(BPFDSL, IsAllowDeny) {
  ResultExpr allow = Allow();
  EXPECT_TRUE(allow->IsAllow());
  EXPECT_FALSE(allow->IsDeny());

  ResultExpr error = Error(ENOENT);
  EXPECT_FALSE(error->IsAllow());
  EXPECT_TRUE(error->IsDeny());

  ResultExpr trace = Trace(42);
  EXPECT_FALSE(trace->IsAllow());
  EXPECT_FALSE(trace->IsDeny());

  ResultExpr trap = Trap(DummyTrap, nullptr);
  EXPECT_FALSE(trap->IsAllow());
  EXPECT_TRUE(trap->IsDeny());

  const Arg<int> arg(0);
  ResultExpr maybe = If(arg == 0, Allow()).Else(Error(EPERM));
  EXPECT_FALSE(maybe->IsAllow());
  EXPECT_FALSE(maybe->IsDeny());
}

TEST(BPFDSL, HasUnsafeTraps) {
  ResultExpr allow = Allow();
  EXPECT_FALSE(allow->HasUnsafeTraps());

  ResultExpr safe = Trap(DummyTrap, nullptr);
  EXPECT_FALSE(safe->HasUnsafeTraps());

  ResultExpr unsafe = UnsafeTrap(DummyTrap, nullptr);
  EXPECT_TRUE(unsafe->HasUnsafeTraps());

  const Arg<int> arg(0);
  ResultExpr maybe = If(arg == 0, allow).Else(unsafe);
  EXPECT_TRUE(maybe->HasUnsafeTraps());
}

}  // namespace
}  // namespace bpf_dsl
}  // namespace sandbox
