// Copyright (c) 2012 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 "brillo/process/process.h"

#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <map>
#include <memory>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/process/process_metrics.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/time/time.h>

#ifndef __linux__
#define setresuid(_u1, _u2, _u3) setreuid(_u1, _u2)
#define setresgid(_g1, _g2, _g3) setregid(_g1, _g2)
#endif  // !__linux__

namespace brillo {

namespace {

// This process is used to open a file and dup2() into a file descriptor in the
// child process after fork().
void OpenFileAndDup2Fd(const std::string& filename, int fd) {
  int output_handle = HANDLE_EINTR(
      open(filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, 0666));
  if (output_handle < 0) {
    PLOG(ERROR) << "Could not create " << filename;
    // Avoid exit() to avoid atexit handlers from parent.
    _exit(Process::kErrorExitStatus);
  }
  HANDLE_EINTR(dup2(output_handle, fd));
  IGNORE_EINTR(close(output_handle));
}

}  // namespace

bool ReturnTrue() {
  return true;
}

Process::Process() {}

Process::~Process() {}

bool Process::ProcessExists(pid_t pid) {
  return base::DirectoryExists(
      base::FilePath(base::StringPrintf("/proc/%d", pid)));
}

ProcessImpl::ProcessImpl()
    : pid_(0),
      uid_(-1),
      gid_(-1),
      pre_exec_(base::Bind(&ReturnTrue)),
      search_path_(false),
      inherit_parent_signal_mask_(false),
      close_unused_file_descriptors_(false) {}

ProcessImpl::~ProcessImpl() {
  Reset(0);
}

void ProcessImpl::AddArg(const std::string& arg) {
  arguments_.push_back(arg);
}

void ProcessImpl::RedirectDevNull(int child_fd) {
  RedirectUsingFile(child_fd, "/dev/null");
}

void ProcessImpl::RedirectInput(const std::string& input_file) {
  stdin_.type_ = FileDescriptorRedirectType::kFile;
  stdin_.filename_ = input_file;
}

void ProcessImpl::RedirectOutput(const std::string& output_file) {
  RedirectUsingFile(STDOUT_FILENO, output_file);
  RedirectUsingFile(STDERR_FILENO, output_file);
}

void ProcessImpl::RedirectOutputToMemory(bool combine) {
  RedirectUsingMemory(STDOUT_FILENO);
  if (combine) {
    stderr_.parent_fd_ = dup(stdout_.parent_fd_);
    stderr_.type_ = FileDescriptorRedirectType::kMemory;
  } else {
    RedirectUsingMemory(STDERR_FILENO);
  }
}

void ProcessImpl::RedirectUsingFile(int child_fd,
                                    const std::string& output_file) {
  switch (child_fd) {
    case STDOUT_FILENO:
      stdout_.type_ = FileDescriptorRedirectType::kFile;
      stdout_.filename_ = output_file;
      break;
    case STDERR_FILENO:
      stderr_.type_ = FileDescriptorRedirectType::kFile;
      stderr_.filename_ = output_file;
      break;
    default:
      LOG(ERROR) << "Invalid file descriptor " << child_fd
                 << " redirect to /dev/null";
  }
}

void ProcessImpl::RedirectUsingMemory(int child_fd) {
  int parent_fd = memfd_create(base::NumberToString(child_fd).c_str(), 0);
  if (parent_fd < 0) {
    PLOG(ERROR) << "Could not memfd_create for " << child_fd;
    return;
  }
  switch (child_fd) {
    case STDOUT_FILENO:
      stdout_.parent_fd_ = parent_fd;
      stdout_.type_ = FileDescriptorRedirectType::kMemory;
      break;
    case STDERR_FILENO:
      stderr_.parent_fd_ = parent_fd;
      stderr_.type_ = FileDescriptorRedirectType::kMemory;
      break;
    default:
      LOG(ERROR) << "Invalid file descriptor " << child_fd
                 << " redirect to memfd";
      IGNORE_EINTR(close(parent_fd));
      return;
  }
}

void ProcessImpl::RedirectUsingPipe(int child_fd, bool is_input) {
  PipeInfo info;
  info.is_input_ = is_input;
  info.is_bound_ = false;
  pipe_map_[child_fd] = info;
}

void ProcessImpl::BindFd(int parent_fd, int child_fd) {
  PipeInfo info;
  info.is_bound_ = true;

  // info.child_fd_ is the 'child half' of the pipe, which gets dup2()ed into
  // place over child_fd. Since we already have the child we want to dup2() into
  // place, we can set info.child_fd_ to parent_fd and leave info.parent_fd_
  // invalid.
  info.child_fd_ = parent_fd;
  info.parent_fd_ = -1;
  pipe_map_[child_fd] = info;
}

void ProcessImpl::SetCloseUnusedFileDescriptors(bool close_unused_fds) {
  close_unused_file_descriptors_ = close_unused_fds;
}

void ProcessImpl::SetUid(uid_t uid) {
  uid_ = uid;
}

void ProcessImpl::SetGid(gid_t gid) {
  gid_ = gid;
}

void ProcessImpl::SetCapabilities(uint64_t /*capmask*/) {
  // No-op, since ProcessImpl does not support sandboxing.
  return;
}

void ProcessImpl::ApplySyscallFilter(const std::string& /*path*/) {
  // No-op, since ProcessImpl does not support sandboxing.
  return;
}

void ProcessImpl::EnterNewPidNamespace() {
  // No-op, since ProcessImpl does not support sandboxing.
  return;
}

void ProcessImpl::SetInheritParentSignalMask(bool inherit) {
  inherit_parent_signal_mask_ = inherit;
}

void ProcessImpl::SetPreExecCallback(const PreExecCallback& cb) {
  pre_exec_ = cb;
}

void ProcessImpl::SetSearchPath(bool search_path) {
  search_path_ = search_path;
}

int ProcessImpl::GetOutputFd(int child_fd) {
  switch (child_fd) {
    case STDOUT_FILENO:
      return stdout_.type_ == FileDescriptorRedirectType::kMemory
                 ? stdout_.parent_fd_
                 : -1;
    case STDERR_FILENO:
      return stderr_.type_ == FileDescriptorRedirectType::kMemory
                 ? stderr_.parent_fd_
                 : -1;
    default:
      return -1;
  }
}

std::string ProcessImpl::GetOutputString(int child_fd) {
  int fd = GetOutputFd(child_fd);
  std::string output;

  if (fd < 0)
    return output;

  struct stat st;

  if (fstat(fd, &st)) {
    PLOG(ERROR) << "Failed to stat memfd";
    return output;
  }

  ssize_t remaining_read_bytes = st.st_size, bytes_read = 0;
  output.resize(remaining_read_bytes);

  while (true) {
    const ssize_t count = HANDLE_EINTR(
        pread(fd, &output[bytes_read], output.size() - bytes_read, bytes_read));
    if (count < 0) {
      PLOG(ERROR) << "Failed to read from fd";
      return std::string();
    }

    bytes_read += count;

    if (bytes_read == output.size())
      return output;
  }
}

int ProcessImpl::GetPipe(int child_fd) {
  PipeMap::iterator i = pipe_map_.find(child_fd);
  if (i == pipe_map_.end())
    return -1;
  else
    return i->second.parent_fd_;
}

bool ProcessImpl::PopulatePipeMap() {
  // Verify all target fds are already open.  With this assumption we
  // can be sure that the pipe fds created below do not overlap with
  // any of the target fds which simplifies how we dup2 to them.  Note
  // that multi-threaded code could close i->first between this loop
  // and the next.
  for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) {
    struct stat stat_buffer;
    if (fstat(i->first, &stat_buffer) < 0) {
      int saved_errno = errno;
      LOG(ERROR) << "Unable to fstat fd " << i->first << ": " << saved_errno;
      return false;
    }
  }

  for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) {
    if (i->second.is_bound_) {
      // already have a parent fd, and the child fd gets dup()ed later.
      continue;
    }
    int pipefds[2];
    if (pipe(pipefds) < 0) {
      int saved_errno = errno;
      LOG(ERROR) << "pipe call failed with: " << saved_errno;
      return false;
    }
    if (i->second.is_input_) {
      // pipe is an input from the prospective of the child.
      i->second.parent_fd_ = pipefds[1];
      i->second.child_fd_ = pipefds[0];
    } else {
      i->second.parent_fd_ = pipefds[0];
      i->second.child_fd_ = pipefds[1];
    }
  }
  return true;
}

bool ProcessImpl::IsFileDescriptorInPipeMap(int fd) const {
  for (const auto& pipe : pipe_map_) {
    if (fd == pipe.second.parent_fd_ || fd == pipe.second.child_fd_ ||
        fd == pipe.first) {
      return true;
    }
  }
  return false;
}

void ProcessImpl::CloseUnusedFileDescriptors() {
  size_t max_fds = base::GetMaxFds();
  for (size_t i = 0; i < max_fds; i++) {
    const int fd = static_cast<int>(i);

    // Ignore STD file descriptors.
    if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) {
      continue;
    }

    // Ignore redirect memfds for stdout and stderr.
    if (fd == stdout_.parent_fd_ || fd == stderr_.parent_fd_) {
      continue;
    }

    // Ignore file descriptors used by the PipeMap, they will be handled
    // by this process later on.
    if (IsFileDescriptorInPipeMap(fd)) {
      continue;
    }

    // Since we're just trying to close anything we can find,
    // ignore any error return values of close().
    IGNORE_EINTR(close(fd));
  }
}

bool ProcessImpl::Start() {
  // If no arguments are provided, fail.
  if (arguments_.empty()) {
    return false;
  }
  std::unique_ptr<char*[]> argv =
      std::make_unique<char*[]>(arguments_.size() + 1);

  for (size_t i = 0; i < arguments_.size(); ++i)
    argv[i] = const_cast<char*>(arguments_[i].c_str());

  argv[arguments_.size()] = nullptr;

  if (!PopulatePipeMap()) {
    LOG(ERROR) << "Failing to start because pipe creation failed";
    return false;
  }

  pid_t pid = fork();
  int saved_errno = errno;
  if (pid < 0) {
    LOG(ERROR) << "Fork failed: " << saved_errno;
    Reset(0);
    return false;
  }

  if (pid == 0) {
    // Executing inside the child process.
    // Close unused file descriptors.
    if (close_unused_file_descriptors_) {
      CloseUnusedFileDescriptors();
    }
    // Close parent's side of the child pipes. dup2 ours into place and
    // then close our ends.
    for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) {
      if (i->second.parent_fd_ != -1)
        IGNORE_EINTR(close(i->second.parent_fd_));
      // If we want to bind a fd to the same fd in the child, we don't need to
      // close and dup2 it.
      if (i->second.child_fd_ == i->first)
        continue;
      HANDLE_EINTR(dup2(i->second.child_fd_, i->first));
    }
    // Defer the actual close() of the child fd until afterward; this lets the
    // same child fd be bound to multiple fds using BindFd. Don't close the fd
    // if it was bound to itself.
    for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) {
      if (i->second.child_fd_ == i->first)
        continue;
      IGNORE_EINTR(close(i->second.child_fd_));
    }

    if (stdin_.type_ == FileDescriptorRedirectType::kFile &&
        !stdin_.filename_.empty()) {
      int input_handle = HANDLE_EINTR(
          open(stdin_.filename_.c_str(), O_RDONLY | O_NOFOLLOW | O_NOCTTY));
      if (input_handle < 0) {
        PLOG(ERROR) << "Could not open " << stdin_.filename_;
        // Avoid exit() to avoid atexit handlers from parent.
        _exit(kErrorExitStatus);
      }

      // It's possible input_handle is already stdin. But if not, we need
      // to dup into that file descriptor and close the original.
      if (input_handle != STDIN_FILENO) {
        if (HANDLE_EINTR(dup2(input_handle, STDIN_FILENO)) < 0) {
          PLOG(ERROR) << "Could not dup fd to stdin for " << stdin_.filename_;
          _exit(kErrorExitStatus);
        }
        IGNORE_EINTR(close(input_handle));
      }
    }

    switch (stdout_.type_) {
      case FileDescriptorRedirectType::kFile:
        if (!stdout_.filename_.empty()) {
          OpenFileAndDup2Fd(stdout_.filename_, STDOUT_FILENO);
        }
        break;
      case FileDescriptorRedirectType::kMemory:
        HANDLE_EINTR(dup2(stdout_.parent_fd_, STDOUT_FILENO));
        IGNORE_EINTR(close(stdout_.parent_fd_));
        break;
      default:
        VLOG(2) << "Ignoring stdout";
    }

    switch (stderr_.type_) {
      case FileDescriptorRedirectType::kFile:
        if (!stderr_.filename_.empty()) {
          if (stderr_.filename_ == stdout_.filename_) {
            HANDLE_EINTR(dup2(STDOUT_FILENO, STDERR_FILENO));
          } else {
            OpenFileAndDup2Fd(stderr_.filename_, STDERR_FILENO);
          }
        }
        break;
      case FileDescriptorRedirectType::kMemory:
        HANDLE_EINTR(dup2(stderr_.parent_fd_, STDERR_FILENO));
        IGNORE_EINTR(close(stderr_.parent_fd_));
        break;
      default:
        VLOG(2) << "Ignoring stderr";
    }

    if (gid_ != static_cast<gid_t>(-1) && setresgid(gid_, gid_, gid_) < 0) {
      int saved_errno = errno;
      LOG(ERROR) << "Unable to set GID to " << gid_ << ": " << saved_errno;
      _exit(kErrorExitStatus);
    }
    if (uid_ != static_cast<uid_t>(-1) && setresuid(uid_, uid_, uid_) < 0) {
      int saved_errno = errno;
      LOG(ERROR) << "Unable to set UID to " << uid_ << ": " << saved_errno;
      _exit(kErrorExitStatus);
    }
    if (!pre_exec_.Run()) {
      LOG(ERROR) << "Pre-exec callback failed";
      _exit(kErrorExitStatus);
    }
    // Reset signal mask for the child process if not inheriting signal mask
    // from the parent process.
    if (!inherit_parent_signal_mask_) {
      sigset_t signal_mask;
      CHECK_EQ(0, sigemptyset(&signal_mask));
      CHECK_EQ(0, sigprocmask(SIG_SETMASK, &signal_mask, nullptr));
    }
    if (search_path_) {
      execvp(argv[0], &argv[0]);
    } else {
      execv(argv[0], &argv[0]);
    }
    PLOG(ERROR) << "Exec of " << argv[0] << " failed";
    _exit(kErrorExitStatus);
  } else {
    // Still executing inside the parent process with known child pid.
    arguments_.clear();
    UpdatePid(pid);
    // Close our copy of child side pipes only if we created those pipes.
    for (const auto& i : pipe_map_) {
      if (!i.second.is_bound_) {
        IGNORE_EINTR(close(i.second.child_fd_));
      }
    }
  }
  return true;
}

int ProcessImpl::Wait() {
  int status = 0;
  if (pid_ == 0) {
    LOG(ERROR) << "Process not running";
    return -1;
  }
  if (HANDLE_EINTR(waitpid(pid_, &status, 0)) < 0) {
    int saved_errno = errno;
    LOG(ERROR) << "Problem waiting for pid " << pid_ << ": " << saved_errno;
    return -1;
  }
  pid_t old_pid = pid_;
  // Update the pid to 0 - do not Reset as we do not want to try to
  // kill the process that has just exited.
  UpdatePid(0);
  if (!WIFEXITED(status)) {
    DCHECK(WIFSIGNALED(status))
        << old_pid << " neither exited, nor died on a signal?";
    LOG(ERROR) << "Process " << old_pid
               << " did not exit normally: " << WTERMSIG(status);
    return -1;
  }
  return WEXITSTATUS(status);
}

int ProcessImpl::Run() {
  if (!Start()) {
    return -1;
  }
  return Wait();
}

pid_t ProcessImpl::pid() {
  return pid_;
}

bool ProcessImpl::Kill(int signal, int timeout) {
  if (pid_ == 0) {
    // Passing pid == 0 to kill is committing suicide.  Check specifically.
    LOG(ERROR) << "Process not running";
    return false;
  }
  if (kill(pid_, signal) < 0) {
    PLOG(ERROR) << "Unable to send signal to " << pid_;
    return false;
  }
  base::TimeTicks start_signal = base::TimeTicks::Now();
  do {
    int status = 0;
    pid_t w = waitpid(pid_, &status, WNOHANG);
    if (w < 0) {
      if (errno == ECHILD)
        return true;
      PLOG(ERROR) << "Waitpid returned " << w;
      return false;
    }
    if (w > 0) {
      Reset(0);
      return true;
    }
    usleep(100);
  } while ((base::TimeTicks::Now() - start_signal).InSecondsF() <= timeout);
  LOG(INFO) << "process " << pid_ << " did not exit from signal " << signal
            << " in " << timeout << " seconds";
  return false;
}

void ProcessImpl::UpdatePid(pid_t new_pid) {
  pid_ = new_pid;
}

void ProcessImpl::Reset(pid_t new_pid) {
  arguments_.clear();
  // Close our side of all pipes to this child giving the child to
  // handle sigpipes and shutdown nicely, though likely it won't
  // have time.
  for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i)
    IGNORE_EINTR(close(i->second.parent_fd_));
  pipe_map_.clear();
  IGNORE_EINTR(close(stdout_.parent_fd_));
  IGNORE_EINTR(close(stderr_.parent_fd_));
  stderr_ = stdout_ = stdin_ = StandardFileDescriptorInfo();
  if (pid_)
    Kill(SIGKILL, 0);
  UpdatePid(new_pid);
}

bool ProcessImpl::ResetPidByFile(const std::string& pid_file) {
  std::string contents;
  if (!base::ReadFileToString(base::FilePath(pid_file), &contents)) {
    LOG(ERROR) << "Could not read pid file" << pid_file;
    return false;
  }
  base::TrimWhitespaceASCII(contents, base::TRIM_TRAILING, &contents);
  int64_t pid_int64 = 0;
  if (!base::StringToInt64(contents, &pid_int64)) {
    LOG(ERROR) << "Unexpected pid file contents";
    return false;
  }
  Reset(pid_int64);
  return true;
}

pid_t ProcessImpl::Release() {
  pid_t old_pid = pid_;
  pid_ = 0;
  return old_pid;
}

}  // namespace brillo
