// Copyright 2017 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 "run_oci/run_oci_utils.h"

#include <fcntl.h>
#include <mntent.h>
#include <stdio.h>
#include <sys/capability.h>
#include <sys/epoll.h>
#include <sys/mount.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <string>
#include <type_traits>
#include <utility>

#include <base/files/file_util.h>
#include <base/stl_util.h>
#include <base/strings/string_piece.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <brillo/key_value_store.h>
#include <brillo/syslog_logging.h>
#include <libminijail.h>
#include <libmount/libmount.h>

// Avoid including syslog.h because it interacts badly with base::logging.
extern "C" void syslog(int priority, const char* format, ...);

namespace run_oci {

namespace {

// We avoid using LOG_* because they interacts badly with base::logging, which
// re-defines LOG_* and causes all sorts of confusion.
constexpr int kSyslogLogWarningPriority = 4;
constexpr int kSyslogLogInfoPriority = 6;

// Creates a pipe where the read end of it is made to be close-on-exec and the
// write end of it is associated with one of the well-known stdio FDs (e.g.
// STDOUT_FILENO/STDERR_FILENO).
bool CreateStdioPipe(base::ScopedFD* pipe_read_fd, int stdio_fd) {
  base::ScopedFD pipe_write_fd;

  if (!Pipe(pipe_read_fd, &pipe_write_fd, O_CLOEXEC)) {
    PLOG(ERROR) << "Failed to create pipe for " << stdio_fd;
    return false;
  }

  if (pipe_write_fd.get() == stdio_fd) {
    // The write fd is already the correct fd number, but it needs to have the
    // close-on-exec flag cleared.
    if (fcntl(pipe_write_fd.get(), F_SETFD, 0) == -1) {
      PLOG(ERROR) << "Failed to set FD_CLOEXEC on read end of pipe for "
                  << stdio_fd;
      return false;
    }
    // Finally, release it so that it is not closed upon returning.
    ignore_result(pipe_write_fd.release());
  } else {
    if (dup2(pipe_write_fd.get(), stdio_fd) == -1) {
      PLOG(ERROR) << "Failed to redirect stdio for " << stdio_fd;
      return false;
    }
  }

  return true;
}

bool IsTestImage() {
  brillo::KeyValueStore store;
  std::string channel;
  if (!store.Load(base::FilePath("/etc/lsb-release"))) {
    LOG(WARNING) << "Failed to parse /etc/lsb-release, assuming non-test image";
    return false;
  }

  if (!store.GetString("CHROMEOS_RELEASE_TRACK", &channel)) {
    LOG(WARNING) << "Couldn't find release track an /etc/lsb-release, assuming "
                    "non-test image";
    return false;
  }

  return base::StartsWith(channel, "test", base::CompareCase::SENSITIVE);
}

}  // namespace

SyslogStdioAdapter::SyslogStdioAdapter(base::Process child)
    : child_(std::move(child)) {}

SyslogStdioAdapter::~SyslogStdioAdapter() {
  if (!child_.Terminate(0 /* exit_code */, true /* wait */))
    LOG(ERROR) << "Failed to terminate logger process";
}

std::unique_ptr<SyslogStdioAdapter> SyslogStdioAdapter::Create() {
  base::ScopedFD stdout_pipe_read_fd, stderr_pipe_read_fd;

  if (!CreateStdioPipe(&stdout_pipe_read_fd, STDOUT_FILENO))
    return nullptr;
  if (!CreateStdioPipe(&stderr_pipe_read_fd, STDERR_FILENO))
    return nullptr;

  // Redirect all minijail logs to avoid them appearing in multiple places.
  minijail_log_to_fd(STDOUT_FILENO, kSyslogLogInfoPriority);

  brillo::SetLogFlags(brillo::kLogToSyslog | brillo::kLogHeader);
  logging::SetLogItems(false /* pid */, false /* tid */, false /* timestamp */,
                       false /* tick_count */);

  pid_t child = fork();
  if (child == -1) {
    PLOG(ERROR) << "Failed to fork";
    return nullptr;
  }

  if (child == 0) {
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    SyslogStdioAdapter::RunLoop(std::move(stdout_pipe_read_fd),
                                std::move(stderr_pipe_read_fd));
    _exit(1);
  }

  return std::unique_ptr<SyslogStdioAdapter>(
      new SyslogStdioAdapter(base::Process(child)));
}

// static
void SyslogStdioAdapter::RunLoop(base::ScopedFD stdout_fd,
                                 base::ScopedFD stderr_fd) {
  base::ScopedFD epollfd(epoll_create(1 /*arbitrary, ignored by kernel*/));
  if (!epollfd.is_valid()) {
    PLOG(ERROR) << "Failed to open epoll fd";
    return;
  }

  struct EpollDescriptor {
    base::ScopedFD* fd;
    const char* name;
    int priority;
  } epoll_descriptors[2] = {{&stdout_fd, "stdout", kSyslogLogInfoPriority},
                            {&stderr_fd, "stderr", kSyslogLogWarningPriority}};
  for (auto& descriptor : epoll_descriptors) {
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.ptr = &descriptor;
    if (epoll_ctl(epollfd.get(), EPOLL_CTL_ADD, descriptor.fd->get(), &ev) ==
        -1) {
      PLOG(ERROR) << "Failed to register " << descriptor.name;
      return;
    }
  }

  char buffer[4096];
  struct epoll_event events[base::size(epoll_descriptors)];
  while (true) {
    int nfds =
        HANDLE_EINTR(epoll_wait(epollfd.get(), events, base::size(events), -1));
    if (nfds == -1) {
      PLOG(ERROR) << "Failed to epoll_wait";
      return;
    }

    for (int i = 0; i < nfds; i++) {
      EpollDescriptor* descriptor =
          reinterpret_cast<EpollDescriptor*>(events[i].data.ptr);
      ssize_t bytes =
          HANDLE_EINTR(read(descriptor->fd->get(), buffer, sizeof(buffer)));
      if (bytes <= 0) {
        PLOG(ERROR) << "Failed to read from " << descriptor->name;
        epoll_ctl(epollfd.get(), EPOLL_CTL_DEL, descriptor->fd->get(), nullptr);
        descriptor->fd->reset();
        continue;
      }
      if (bytes == 0) {
        LOG(ERROR) << descriptor->name << " was closed";
        epoll_ctl(epollfd.get(), EPOLL_CTL_DEL, descriptor->fd->get(), nullptr);
        descriptor->fd->reset();
        continue;
      }

      // This assumes that the writer's output is buffered and flushed on a
      // line-by-line basis. This is true in practice and requires much simpler
      // code, but may lead to lines that straddle a buffer size or partial
      // lines that are output using raw write(2) syscalls being split across
      // two read(2) syscalls.
      base::StringPiece lines(buffer, bytes);
      for (const auto& line : base::SplitString(
               lines, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
        syslog(descriptor->priority, "[%s] %s", descriptor->name, line.data());
      }
    }
  }
}

bool Mountpoint::operator==(const Mountpoint& other) const {
  return path == other.path && mountflags == other.mountflags &&
         data_string == other.data_string;
}

std::string ParseMountOptions(const std::vector<std::string>& options,
                              int* mount_flags_out,
                              int* negated_mount_flags_out,
                              int* bind_flags_out,
                              int* mount_propagation_flags_out,
                              bool* loopback_out,
                              std::string* verity_options) {
  std::string option_string_out;
  *mount_flags_out = 0;
  *negated_mount_flags_out = 0;
  *bind_flags_out = 0;
  *mount_propagation_flags_out = 0;
  *loopback_out = false;

  const struct libmnt_optmap* linux_option_map =
      mnt_get_builtin_optmap(MNT_LINUX_MAP);

  constexpr int kMountPropagationFlagsMask =
      MS_PRIVATE | MS_SLAVE | MS_SHARED | MS_UNBINDABLE;

  for (const auto& option : options) {
    const struct libmnt_optmap* map_entry = nullptr;

    for (const struct libmnt_optmap* it = linux_option_map; it->name; ++it) {
      if (option == it->name && it->id) {
        map_entry = it;
        break;
      }
    }

    if (map_entry) {
      // This is a known flag name.
      if (map_entry->id & MS_BIND) {
        *bind_flags_out |= map_entry->id;
      } else if (map_entry->id & kMountPropagationFlagsMask) {
        *mount_propagation_flags_out |= map_entry->id;
      } else if (map_entry->mask & MNT_INVERT) {
        *negated_mount_flags_out |= map_entry->id;
      } else {
        *mount_flags_out |= map_entry->id;
      }
    } else if (option == "loop") {
      *loopback_out = true;
    } else if (base::StartsWith(option, "dm=", base::CompareCase::SENSITIVE)) {
      *verity_options = option.substr(3, std::string::npos);
    } else {
      // Unknown options get appended to the string passed to mount data.
      if (!option_string_out.empty())
        option_string_out += ",";
      option_string_out += option;
    }
  }

  return option_string_out;
}

std::vector<Mountpoint> GetMountpointsUnder(
    const base::FilePath& root, const base::FilePath& procSelfMountsPath) {
  base::ScopedFILE mountinfo(fopen(procSelfMountsPath.value().c_str(), "r"));
  if (!mountinfo) {
    PLOG(ERROR) << "Failed to open " << procSelfMountsPath.value();
    return std::vector<Mountpoint>();
  }

  struct mntent mount_entry;

  std::string line;
  char buffer[1024];
  std::vector<Mountpoint> mountpoints;
  while (getmntent_r(mountinfo.get(), &mount_entry, buffer, sizeof(buffer))) {
    // Only return paths that are under |root|.
    const std::string path = mount_entry.mnt_dir;
    if (path.compare(0, root.value().size(), root.value()) != 0)
      continue;

    int mount_flags, negated_mount_flags, bind_mount_flags,
        mount_propagation_flags;
    bool loopback;
    std::string verity_options;
    std::string options = ParseMountOptions(
        base::SplitString(mount_entry.mnt_opts, ",", base::TRIM_WHITESPACE,
                          base::SPLIT_WANT_NONEMPTY),
        &mount_flags, &negated_mount_flags, &bind_mount_flags,
        &mount_propagation_flags, &loopback, &verity_options);
    mountpoints.emplace_back(
        Mountpoint{base::FilePath(path), mount_flags, options});
  }

  return mountpoints;
}

bool HasCapSysAdmin() {
  if (!CAP_IS_SUPPORTED(CAP_SYS_ADMIN))
    return false;

  std::unique_ptr<std::remove_pointer_t<cap_t>, decltype(&cap_free)> caps(
      cap_get_proc(), &cap_free);
  if (!caps) {
    PLOG(ERROR) << "Failed to get process' capabilities";
    return false;
  }

  cap_flag_value_t cap_value;
  if (cap_get_flag(caps.get(), CAP_SYS_ADMIN, CAP_EFFECTIVE, &cap_value) != 0) {
    PLOG(ERROR) << "Failed to get the value of CAP_SYS_ADMIN";
    return false;
  }
  return cap_value == CAP_SET;
}

bool RedirectLoggingAndStdio(const base::FilePath& log_file) {
  base::ScopedFD log_fd(HANDLE_EINTR(
      open(log_file.value().c_str(), O_CREAT | O_WRONLY | O_APPEND, 0644)));
  if (!log_fd.is_valid()) {
    PLOG(ERROR) << "Failed to open log file '" << log_file.value() << "'";
    return false;
  }
  // Redirecting stdout/stderr for the hooks' benefit.
  if (dup2(log_fd.get(), STDOUT_FILENO) == -1) {
    PLOG(ERROR) << "Failed to redirect stdout";
    return false;
  }
  if (dup2(log_fd.get(), STDERR_FILENO) == -1) {
    PLOG(ERROR) << "Failed to redirect stderr";
    return false;
  }
  // Redirect all minijail logs to make them easier to find.
  minijail_log_to_fd(STDERR_FILENO, kSyslogLogInfoPriority);

  brillo::SetLogFlags(brillo::kLogHeader | brillo::kLogToStderr);
  logging::SetLogItems(true /* pid */, false /* tid */, true /* timestamp */,
                       false /* tick_count */);
  return true;
}

bool Pipe(base::ScopedFD* read_fd, base::ScopedFD* write_fd, int flags) {
  int pipe_fds[2];
  if (HANDLE_EINTR(pipe2(pipe_fds, flags)) != 0)
    return false;
  read_fd->reset(pipe_fds[0]);
  write_fd->reset(pipe_fds[1]);
  return true;
}

brillo::SafeFD OpenOciConfigSafelyInternal(const base::FilePath& config_path,
                                           bool enable_noexec_check) {
  brillo::SafeFD::SafeFDResult result(
      brillo::SafeFD::Root().first.OpenExistingFile(config_path,
                                                    O_RDONLY | O_CLOEXEC));
  if (brillo::SafeFD::IsError(result.second)) {
    LOG(ERROR) << "Failed to open " << config_path.value() << " with error "
               << static_cast<int>(result.second);
    return brillo::SafeFD();
  }

  brillo::SafeFD fd(std::move(result.first));
  struct statvfs buf;
  if (HANDLE_EINTR(fstatvfs(fd.get(), &buf)) < 0) {
    PLOG(ERROR) << "Failed to statvfs container config: "
                << config_path.value();
    return brillo::SafeFD();
  }

  if (enable_noexec_check && (buf.f_flag & ST_NOEXEC)) {
    LOG(ERROR) << config_path.value() << " is on a noexec filesystem";
    errno = EPERM;
    return brillo::SafeFD();
  }
  return fd;
}

brillo::SafeFD OpenOciConfigSafely(const base::FilePath& config_path) {
  // Don't check the flag on a test image. security.RunOCI relies on configs on
  // a writable partition.
  return OpenOciConfigSafelyInternal(config_path,
                                     !IsTestImage() /* enable_noexec_check */);
}

brillo::SafeFD OpenOciConfigSafelyForTest(const base::FilePath& config_path,
                                          bool enable_noexec_check) {
  return OpenOciConfigSafelyInternal(config_path, enable_noexec_check);
}

}  // namespace run_oci
