// 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/wait.h>
#include <unistd.h>

#include <type_traits>
#include <utility>

#include <base/files/file_util.h>
#include <base/strings/string_piece.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.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;
}

}  // 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[arraysize(epoll_descriptors)];
  while (true) {
    int nfds =
        HANDLE_EINTR(epoll_wait(epollfd.get(), events, arraysize(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.as_string(), "\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;
}

}  // namespace run_oci
