// 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/bind_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/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() = 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_;

  DISALLOW_COPY_AND_ASSIGN(MockCgroup);
};

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() 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,
                                arraysize(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_;

  DISALLOW_COPY_AND_ASSIGN(ContainerTest);
};

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;
}

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"
