// Copyright 2016 The Chromium OS 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 <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <unistd.h>

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/posix/eintr_wrapper.h>
#include <base/stl_util.h>
#include <base/strings/string_split.h>
#include <gtest/gtest.h>

#include "libcontainer/cgroup.h"
#include "libcontainer/config.h"
#include "libcontainer/container.h"
#include "libcontainer/libcontainer.h"
#include "libcontainer/libcontainer_util.h"

namespace libcontainer {

namespace {

using MinijailHookCallback = base::Callback<int()>;

constexpr int kTestCpuShares = 200;
constexpr int kTestCpuQuota = 20000;
constexpr int kTestCpuPeriod = 50000;

struct MockPosixState {
  struct MountArgs {
    std::string source;
    base::FilePath target;
    std::string filesystemtype;
    unsigned long mountflags;
    const void* data;
    bool outside_mount;
  };
  std::vector<MountArgs> mount_args;

  dev_t stat_rdev_ret = makedev(2, 3);

  std::vector<int> kill_sigs;
  base::FilePath mkdtemp_root;
};
MockPosixState* g_mock_posix_state = nullptr;

struct MockCgroupState {
  struct AddedDevice {
    bool allow;
    int major;
    int minor;
    bool read;
    bool write;
    bool modify;
    char type;
  };

  bool freeze_ret = true;
  bool thaw_ret = true;
  bool deny_all_devs_ret = true;
  bool add_device_ret = true;
  bool set_cpu_ret = true;

  int deny_all_devs_called_count;

  std::vector<AddedDevice> added_devices;

  int set_cpu_shares_count;
  int set_cpu_quota_count;
  int set_cpu_period_count;
  int set_cpu_rt_runtime_count;
  int set_cpu_rt_period_count;
};
MockCgroupState* g_mock_cgroup_state = nullptr;

class MockCgroup : public libcontainer::Cgroup {
 public:
  explicit MockCgroup(MockCgroupState* state) : state_(state) {}
  MockCgroup(const MockCgroup&) = delete;
  MockCgroup& operator=(const MockCgroup&) = delete;

  ~MockCgroup() = default;

  static std::unique_ptr<libcontainer::Cgroup> Create(
      base::StringPiece name,
      const base::FilePath& cgroup_root,
      const base::FilePath& cgroup_parent,
      uid_t cgroup_owner,
      gid_t cgroup_group) {
    return std::make_unique<MockCgroup>(g_mock_cgroup_state);
  }

  bool Freeze() override { return state_->freeze_ret; }

  bool Thaw() override { return state_->thaw_ret; }

  bool DenyAllDevices() override {
    ++state_->deny_all_devs_called_count;
    return state_->deny_all_devs_ret;
  }

  bool AddDevice(bool allow,
                 int major,
                 int minor,
                 bool read,
                 bool write,
                 bool modify,
                 char type) override {
    state_->added_devices.emplace_back(MockCgroupState::AddedDevice{
        allow, major, minor, read, write, modify, type});
    return state_->add_device_ret;
  }

  bool SetCpuShares(int shares) override {
    state_->set_cpu_shares_count++;
    return state_->set_cpu_ret;
  }

  bool SetCpuQuota(int quota) override {
    state_->set_cpu_quota_count++;
    return state_->set_cpu_ret;
  }

  bool SetCpuPeriod(int period) override {
    state_->set_cpu_period_count++;
    return state_->set_cpu_ret;
  }

  bool SetCpuRtRuntime(int rt_runtime) override {
    state_->set_cpu_rt_runtime_count++;
    return state_->set_cpu_ret;
  }

  bool SetCpuRtPeriod(int rt_period) override {
    state_->set_cpu_rt_period_count++;
    return state_->set_cpu_ret;
  }

 private:
  MockCgroupState* const state_;
};

struct MockMinijailState {
  std::string alt_syscall_table;
  int ipc_called_count;
  int vfs_called_count;
  int net_called_count;
  int pids_called_count;
  int run_as_init_called_count;
  int user_called_count;
  int cgroups_called_count;
  int wait_called_count;
  int reset_signal_mask_called_count;
  int reset_signal_handlers_called_count;
  int set_supplementary_gids_called_count;
  int pid;
  std::map<minijail_hook_event_t, std::vector<MinijailHookCallback>> hooks;
};
MockMinijailState* g_mock_minijail_state = nullptr;

}  // namespace

TEST(LibcontainerTest, PremountedRunfs) {
  char premounted_runfs[] = "/tmp/cgtest_run/root";
  struct container_config* config = container_config_create();
  ASSERT_NE(nullptr, config);

  container_config_premounted_runfs(config, premounted_runfs);
  const char* result = container_config_get_premounted_runfs(config);
  ASSERT_EQ(0, strcmp(result, premounted_runfs));

  container_config_destroy(config);
}

TEST(LibcontainerTest, PidFilePath) {
  char pid_file_path[] = "/tmp/cgtest_run/root/container.pid";
  struct container_config* config = container_config_create();
  ASSERT_NE(nullptr, config);

  container_config_pid_file(config, pid_file_path);
  const char* result = container_config_get_pid_file(config);
  ASSERT_EQ(0, strcmp(result, pid_file_path));

  container_config_destroy(config);
}

TEST(LibcontainerTest, DumpConfig) {
  struct container_config* config = container_config_create();
  ASSERT_NE(nullptr, config);

  // Confirm that container_config_dump() returns a non-empty string.
  std::unique_ptr<char, decltype(&free)> config_str(
      container_config_dump(config, false /* sort_vector */), free);
  ASSERT_NE(nullptr, config_str.get());
  EXPECT_NE(0U, strlen(config_str.get()));

  // Also confirm that the string has multiple lines.
  EXPECT_LT(1U, base::SplitString(config_str.get(), "\n", base::KEEP_WHITESPACE,
                                  base::SPLIT_WANT_NONEMPTY)
                    .size());

  container_config_destroy(config);
}

class ContainerTest : public ::testing::Test {
 public:
  ContainerTest() = default;
  ContainerTest(const ContainerTest&) = delete;
  ContainerTest& operator=(const ContainerTest&) = delete;

  ~ContainerTest() override = default;

  void SetUp() override {
    g_mock_posix_state = new MockPosixState();
    g_mock_cgroup_state = new MockCgroupState();
    g_mock_minijail_state = new MockMinijailState();
    libcontainer::Cgroup::SetCgroupFactoryForTesting(&MockCgroup::Create);

    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    ASSERT_TRUE(base::CreateTemporaryDirInDir(temp_dir_.GetPath(),
                                              "container_test", &rootfs_));

    mount_flags_ = MS_NOSUID | MS_NODEV | MS_NOEXEC;

    config_.reset(new Config());
    container_config_uid_map(config_->get(), "0 0 4294967295");
    container_config_gid_map(config_->get(), "0 0 4294967295");
    container_config_rootfs(config_->get(), rootfs_.value().c_str());

    static const char* kArgv[] = {
        "/sbin/init",
    };
    container_config_program_argv(config_->get(), kArgv, 1);
    container_config_alt_syscall_table(config_->get(), "testsyscalltable");
    container_config_add_mount(config_->get(), "testtmpfs", "tmpfs", "/tmp",
                               "tmpfs", nullptr, nullptr, mount_flags_, 0, 1000,
                               1000, 0x666, 0, 0);
    container_config_add_device(config_->get(), 'c', "/dev/foo",
                                S_IRWXU | S_IRWXG, 245, 2, 0, 0, 1000, 1001, 1,
                                1, 0);
    // test dynamic minor on /dev/null
    container_config_add_device(config_->get(), 'c', "/dev/null",
                                S_IRWXU | S_IRWXG, 1, -1, 0, 1, 1000, 1001, 1,
                                1, 0);
    static const char* kNamespaces[] = {
        "cgroup", "ipc", "mount", "network", "pid", "user",
    };
    container_config_namespaces(config_->get(), kNamespaces,
                                base::size(kNamespaces));

    container_config_set_cpu_shares(config_->get(), kTestCpuShares);
    container_config_set_cpu_cfs_params(config_->get(), kTestCpuQuota,
                                        kTestCpuPeriod);
    /* Invalid params, so this won't be applied. */
    container_config_set_cpu_rt_params(config_->get(), 20000, 20000);

    base::FilePath rundir;
    ASSERT_TRUE(base::CreateTemporaryDirInDir(temp_dir_.GetPath(),
                                              "container_test_run", &rundir));
    container_.reset(new Container("containerUT", rundir));
    ASSERT_NE(nullptr, container_.get());
  }

  void TearDown() override {
    container_.reset();
    config_.reset();

    ASSERT_TRUE(temp_dir_.Delete());
    delete g_mock_posix_state;
    g_mock_posix_state = nullptr;
    libcontainer::Cgroup::SetCgroupFactoryForTesting(nullptr);
    delete g_mock_cgroup_state;
    delete g_mock_minijail_state;
    g_mock_minijail_state = nullptr;
  }

 protected:
  const Config* config() const { return config_.get(); }

  std::unique_ptr<Config> config_;
  std::unique_ptr<Container> container_;
  int mount_flags_;
  base::FilePath rootfs_;

 private:
  base::ScopedTempDir temp_dir_;
};

TEST_F(ContainerTest, TestMountTmpStart) {
  ASSERT_EQ(0, container_start(container_->get(), config_->get()));
  ASSERT_EQ(2, g_mock_posix_state->mount_args.size());
  EXPECT_EQ(false, g_mock_posix_state->mount_args[1].outside_mount);
  EXPECT_STREQ("tmpfs", g_mock_posix_state->mount_args[1].source.c_str());
  EXPECT_STREQ("/tmp",
               g_mock_posix_state->mount_args[1].target.value().c_str());
  EXPECT_STREQ("tmpfs",
               g_mock_posix_state->mount_args[1].filesystemtype.c_str());
  EXPECT_EQ(g_mock_posix_state->mount_args[1].mountflags,
            static_cast<unsigned long>(mount_flags_));
  EXPECT_EQ(nullptr, g_mock_posix_state->mount_args[1].data);

  EXPECT_EQ(1, g_mock_minijail_state->ipc_called_count);
  EXPECT_EQ(1, g_mock_minijail_state->vfs_called_count);
  EXPECT_EQ(1, g_mock_minijail_state->net_called_count);
  EXPECT_EQ(1, g_mock_minijail_state->pids_called_count);
  EXPECT_EQ(1, g_mock_minijail_state->user_called_count);
  EXPECT_EQ(1, g_mock_minijail_state->cgroups_called_count);
  EXPECT_EQ(1, g_mock_minijail_state->run_as_init_called_count);
  EXPECT_EQ(1, g_mock_cgroup_state->deny_all_devs_called_count);

  ASSERT_EQ(2, g_mock_cgroup_state->added_devices.size());
  EXPECT_EQ(1, g_mock_cgroup_state->added_devices[0].allow);
  EXPECT_EQ(245, g_mock_cgroup_state->added_devices[0].major);
  EXPECT_EQ(2, g_mock_cgroup_state->added_devices[0].minor);
  EXPECT_EQ(1, g_mock_cgroup_state->added_devices[0].read);
  EXPECT_EQ(1, g_mock_cgroup_state->added_devices[0].write);
  EXPECT_EQ(0, g_mock_cgroup_state->added_devices[0].modify);
  EXPECT_EQ('c', g_mock_cgroup_state->added_devices[0].type);

  EXPECT_EQ(1, g_mock_cgroup_state->added_devices[1].allow);
  EXPECT_EQ(1, g_mock_cgroup_state->added_devices[1].major);
  EXPECT_EQ(-1, g_mock_cgroup_state->added_devices[1].minor);
  EXPECT_EQ(1, g_mock_cgroup_state->added_devices[1].read);
  EXPECT_EQ(1, g_mock_cgroup_state->added_devices[1].write);
  EXPECT_EQ(0, g_mock_cgroup_state->added_devices[1].modify);
  EXPECT_EQ('c', g_mock_cgroup_state->added_devices[1].type);

  EXPECT_EQ(1, g_mock_cgroup_state->set_cpu_shares_count);
  EXPECT_EQ(kTestCpuShares, container_config_get_cpu_shares(config_->get()));
  EXPECT_EQ(1, g_mock_cgroup_state->set_cpu_quota_count);
  EXPECT_EQ(kTestCpuQuota, container_config_get_cpu_quota(config_->get()));
  EXPECT_EQ(1, g_mock_cgroup_state->set_cpu_period_count);
  EXPECT_EQ(kTestCpuPeriod, container_config_get_cpu_period(config_->get()));
  EXPECT_EQ(0, g_mock_cgroup_state->set_cpu_rt_runtime_count);
  EXPECT_EQ(0, container_config_get_cpu_rt_runtime(config_->get()));
  EXPECT_EQ(0, g_mock_cgroup_state->set_cpu_rt_period_count);
  EXPECT_EQ(0, container_config_get_cpu_rt_period(config_->get()));

  ASSERT_NE(std::string(), g_mock_minijail_state->alt_syscall_table);
  EXPECT_EQ("testsyscalltable", g_mock_minijail_state->alt_syscall_table);

  EXPECT_EQ(0, container_wait(container_->get()));
  EXPECT_EQ(1, g_mock_minijail_state->wait_called_count);
  EXPECT_EQ(1, g_mock_minijail_state->reset_signal_mask_called_count);
  EXPECT_EQ(1, g_mock_minijail_state->reset_signal_handlers_called_count);
  EXPECT_EQ(0, g_mock_minijail_state->set_supplementary_gids_called_count);
}

TEST_F(ContainerTest, TestKillContainer) {
  ASSERT_EQ(0, container_start(container_->get(), config_->get()));
  EXPECT_EQ(0, container_kill(container_->get()));
  EXPECT_EQ(std::vector<int>{SIGKILL}, g_mock_posix_state->kill_sigs);
  EXPECT_EQ(1, g_mock_minijail_state->wait_called_count);
}

// Does the same as LibcontainerTest.DumpConfig but with more configuration
// parameters similar to the production.
TEST_F(ContainerTest, DumpConfig) {
  struct container_config* config = this->config()->get();
  ASSERT_NE(nullptr, config);
  std::unique_ptr<char, decltype(&free)> config_str(
      container_config_dump(config, true /* sort_vector */), free);
  ASSERT_NE(nullptr, config_str.get());
  EXPECT_NE(0U, strlen(config_str.get()));
  EXPECT_LT(1U, base::SplitString(config_str.get(), "\n", base::KEEP_WHITESPACE,
                                  base::SPLIT_WANT_NONEMPTY)
                    .size());
}

}  // namespace libcontainer

// libc stubs so the UT doesn't need root to call mount, etc.
extern "C" {

extern decltype(chmod) __real_chmod;
int __wrap_chmod(const char* path, mode_t mode) {
  if (!libcontainer::g_mock_posix_state)
    return __real_chmod(path, mode);
  return 0;
}

extern decltype(chown) __real_chown;
int __wrap_chown(const char* path, uid_t owner, gid_t group) {
  if (!libcontainer::g_mock_posix_state)
    return __real_chown(path, owner, group);
  return 0;
}

extern decltype(getuid) __real_getuid;
uid_t __wrap_getuid(void) {
  if (!libcontainer::g_mock_posix_state)
    return __real_getuid();
  return 0;
}

extern decltype(kill) __real_kill;
int __wrap_kill(pid_t pid, int sig) {
  if (!libcontainer::g_mock_posix_state)
    return __real_kill(pid, sig);
  libcontainer::g_mock_posix_state->kill_sigs.push_back(sig);
  return 0;
}

extern decltype(mkdir) __real_mkdir;
int __wrap_mkdir(const char* pathname, mode_t mode) {
  if (!libcontainer::g_mock_posix_state)
    return __real_mkdir(pathname, mode);
  return 0;
}

extern decltype(mkdtemp) __real_mkdtemp;
char* __wrap_mkdtemp(char* template_string) {
  if (!libcontainer::g_mock_posix_state)
    return __real_mkdtemp(template_string);
  libcontainer::g_mock_posix_state->mkdtemp_root =
      base::FilePath(template_string);
  return template_string;
}

extern decltype(mount) __real_mount;
int __wrap_mount(const char* source,
                 const char* target,
                 const char* filesystemtype,
                 unsigned long mountflags,
                 const void* data) {
  if (!libcontainer::g_mock_posix_state)
    return __real_mount(source, target, filesystemtype, mountflags, data);

  libcontainer::g_mock_posix_state->mount_args.emplace_back(
      libcontainer::MockPosixState::MountArgs{source, base::FilePath(target),
                                              filesystemtype, mountflags, data,
                                              true});
  return 0;
}

extern decltype(rmdir) __real_rmdir;
int __wrap_rmdir(const char* pathname) {
  if (!libcontainer::g_mock_posix_state)
    return __real_rmdir(pathname);
  return 0;
}

extern decltype(umount) __real_umount;
int __wrap_umount(const char* target) {
  if (!libcontainer::g_mock_posix_state)
    return __real_umount(target);
  return 0;
}

extern decltype(umount2) __real_umount2;
int __wrap_umount2(const char* target, int flags) {
  if (!libcontainer::g_mock_posix_state)
    return __real_umount2(target, flags);
  return 0;
}

extern decltype(unlink) __real_unlink;
int __wrap_unlink(const char* pathname) {
  if (!libcontainer::g_mock_posix_state)
    return __real_unlink(pathname);
  return 0;
}

extern decltype(__xmknod) __real___xmknod;
int __wrap___xmknod(int ver, const char* pathname, mode_t mode, dev_t* dev) {
  if (!libcontainer::g_mock_posix_state)
    return __real___xmknod(ver, pathname, mode, dev);
  return 0;
}

extern decltype(__xstat) __real___xstat;
int __wrap___xstat(int ver, const char* path, struct stat* buf) {
  if (!libcontainer::g_mock_posix_state)
    return __real___xstat(ver, path, buf);
  buf->st_rdev = libcontainer::g_mock_posix_state->stat_rdev_ret;
  return 0;
}

extern decltype(setns) __real_setns;
int __wrap_setns(int fd, int nstype) {
  if (!libcontainer::g_mock_posix_state)
    return __real_setns(fd, nstype);
  return 0;
}

/* Minijail stubs */
struct minijail* minijail_new(void) {
  return (struct minijail*)0x55;
}

void minijail_destroy(struct minijail* j) {}

int minijail_mount_with_data(struct minijail* j,
                             const char* source,
                             const char* target,
                             const char* filesystemtype,
                             unsigned long mountflags,
                             const char* data) {
  libcontainer::g_mock_posix_state->mount_args.emplace_back(
      libcontainer::MockPosixState::MountArgs{source, base::FilePath(target),
                                              filesystemtype, mountflags, data,
                                              false});
  return 0;
}

void minijail_namespace_user_disable_setgroups(struct minijail* j) {}

void minijail_namespace_vfs(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->vfs_called_count;
}

void minijail_namespace_ipc(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->ipc_called_count;
}

void minijail_namespace_net(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->net_called_count;
}

void minijail_namespace_pids(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->pids_called_count;
}

void minijail_namespace_user(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->user_called_count;
}

void minijail_namespace_cgroups(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->cgroups_called_count;
}

int minijail_uidmap(struct minijail* j, const char* uidmap) {
  return 0;
}

int minijail_gidmap(struct minijail* j, const char* gidmap) {
  return 0;
}

int minijail_enter_pivot_root(struct minijail* j, const char* dir) {
  return 0;
}

void minijail_run_as_init(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->run_as_init_called_count;
}

int minijail_run_pid_pipes_no_preload(struct minijail* j,
                                      const char* filename,
                                      char* const argv[],
                                      pid_t* pchild_pid,
                                      int* pstdin_fd,
                                      int* pstdout_fd,
                                      int* pstderr_fd) {
  libcontainer::g_mock_minijail_state->pid = fork();
  if (libcontainer::g_mock_minijail_state->pid == -1)
    return libcontainer::g_mock_minijail_state->pid;

  if (libcontainer::g_mock_minijail_state->pid == 0) {
    for (minijail_hook_event_t event :
         {MINIJAIL_HOOK_EVENT_PRE_CHROOT, MINIJAIL_HOOK_EVENT_PRE_DROP_CAPS,
          MINIJAIL_HOOK_EVENT_PRE_EXECVE}) {
      auto it = libcontainer::g_mock_minijail_state->hooks.find(event);
      if (it == libcontainer::g_mock_minijail_state->hooks.end())
        continue;
      for (auto& hook : it->second) {
        int rc = hook.Run();
        if (rc)
          _exit(rc);
      }
    }
    _exit(0);
  }

  *pchild_pid = libcontainer::g_mock_minijail_state->pid;
  return 0;
}

int minijail_write_pid_file(struct minijail* j, const char* path) {
  return 0;
}

int minijail_wait(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->wait_called_count;
  int status;
  if (HANDLE_EINTR(
          waitpid(libcontainer::g_mock_minijail_state->pid, &status, 0)) < 0) {
    PLOG(ERROR) << "Failed to wait for minijail";
    return -errno;
  }
  if (!WIFEXITED(status)) {
    LOG(ERROR) << "minijail terminated abnormally: " << std::hex << status;
    return -ECANCELED;
  }
  // Exit status gets truncated to 8 bits. This should sign-extend it so that
  // any negative values we passed are preserved.
  return static_cast<int8_t>(WEXITSTATUS(status));
}

int minijail_use_alt_syscall(struct minijail* j, const char* table) {
  libcontainer::g_mock_minijail_state->alt_syscall_table = table;
  return 0;
}

int minijail_add_to_cgroup(struct minijail* j, const char* cg_path) {
  return 0;
}

int minijail_forward_signals(struct minijail* j) {
  return 0;
}

void minijail_reset_signal_mask(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->reset_signal_mask_called_count;
}

void minijail_reset_signal_handlers(struct minijail* j) {
  ++libcontainer::g_mock_minijail_state->reset_signal_handlers_called_count;
}

void minijail_skip_remount_private(struct minijail* j) {}

int minijail_preserve_fd(struct minijail* j, int parent_fd, int child_fd) {
  return 0;
}

int minijail_add_hook(struct minijail* j,
                      minijail_hook_t hook,
                      void* payload,
                      minijail_hook_event_t event) {
  auto it = libcontainer::g_mock_minijail_state->hooks.insert(
      std::make_pair(event, std::vector<libcontainer::MinijailHookCallback>()));
  it.first->second.emplace_back(base::Bind(hook, base::Unretained(payload)));
  return 0;
}

void minijail_close_open_fds(struct minijail* j) {}

void minijail_set_supplementary_gids(struct minijail* j,
                                     size_t size,
                                     const gid_t* list) {
  ++libcontainer::g_mock_minijail_state->set_supplementary_gids_called_count;
}

}  // extern "C"
