// Copyright 2019 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 "cryptohome/storage/out_of_process_mount_helper.h"

#include <poll.h>
#include <sys/stat.h>
#include <sysexits.h>

#include <algorithm>
#include <map>
#include <memory>
#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/logging.h>
#include <base/strings/stringprintf.h>
#include <brillo/cryptohome.h>
#include <brillo/process/process.h>
#include <brillo/secure_blob.h>

#include "cryptohome/cryptohome_common.h"
#include "cryptohome/cryptohome_metrics.h"
#include "cryptohome/storage/mount_constants.h"
#include "cryptohome/storage/mount_utils.h"

#include "cryptohome/namespace_mounter_ipc.pb.h"

using base::FilePath;
using base::StringPrintf;

namespace {

// Wait up to three seconds for the ephemeral mount to be performed.
// Normally, setting up a full ephemeral mount takes about 300 ms, so
// give ourselves a healthy 10x margin.
constexpr base::TimeDelta kOutOfProcessHelperMountTimeout =
    base::TimeDelta::FromSeconds(3);

// Wait one second for the helper to exit and be reaped.
// The brillo::Process::Kill() function that takes this timeout does not allow
// for sub-second granularity, and waiting more than one second for the helper
// to exit makes little sense: the helper is designed to clean up and exit
// quickly: it takes about 100 ms to clean up ephemeral mounts.
constexpr base::TimeDelta kOutOfProcessHelperReapTimeout =
    base::TimeDelta::FromSeconds(1);

bool WaitForHelper(int read_from_helper, const base::TimeDelta& timeout) {
  struct pollfd poll_fd = {};
  poll_fd.fd = read_from_helper;
  poll_fd.events = POLLIN;

  // While HANDLE_EINTR will restart the timeout, this happening repeatedly
  // should be exceedingly rare.
  int ret = HANDLE_EINTR(poll(&poll_fd, 1U, timeout.InMilliseconds()));

  if (ret < 0) {
    PLOG(ERROR) << "poll(read_from_helper) failed";
    return false;
  }

  if (ret == 0) {
    LOG(ERROR) << "WaitForHelper timed out";
    return false;
  }

  return (poll_fd.revents & POLLIN) == POLLIN;
}

std::map<cryptohome::MountType, cryptohome::OutOfProcessMountRequest_MountType>
    mount_type = {
        // Not mounted.
        {cryptohome::MountType::NONE,
         cryptohome::OutOfProcessMountRequest_MountType_NONE},
        // Encrypted with ecryptfs.
        {cryptohome::MountType::ECRYPTFS,
         cryptohome::OutOfProcessMountRequest_MountType_ECRYPTFS},
        // Encrypted with dircrypto.
        {cryptohome::MountType::DIR_CRYPTO,
         cryptohome::OutOfProcessMountRequest_MountType_DIR_CRYPTO},
        // Ephemeral mount.
        {cryptohome::MountType::EPHEMERAL,
         cryptohome::OutOfProcessMountRequest_MountType_EPHEMERAL},
        // Encrypted with dmcrpyt.
        {cryptohome::MountType::DMCRYPT,
         cryptohome::OutOfProcessMountRequest_MountType_DMCRYPT},
};

}  // namespace

namespace cryptohome {

bool OutOfProcessMountHelper::CanPerformEphemeralMount() const {
  return !helper_process_ || helper_process_->pid() == 0;
}

bool OutOfProcessMountHelper::MountPerformed() const {
  return helper_process_ && helper_process_->pid() > 0;
}

bool OutOfProcessMountHelper::IsPathMounted(const base::FilePath& path) const {
  return mounted_paths_.count(path.value()) > 0;
}

void OutOfProcessMountHelper::KillOutOfProcessHelperIfNecessary() {
  if (helper_process_->pid() == 0) {
    return;
  }

  ReportTimerStart(kOOPMountCleanupTimer);

  if (helper_process_->Kill(SIGTERM,
                            kOutOfProcessHelperReapTimeout.InSeconds())) {
    ReportTimerStop(kOOPMountCleanupTimer);
    ReportOOPMountCleanupResult(OOPMountCleanupResult::kSuccess);
  } else {
    LOG(ERROR) << "Failed to send SIGTERM to OOP mount helper";

    // If the process didn't exit on SIGTERM, attempt SIGKILL.
    if (helper_process_->Kill(SIGKILL, 0)) {
      // If SIGKILL succeeds (with SIGTERM having failed) log the fact that
      // poking failed.
      ReportOOPMountCleanupResult(OOPMountCleanupResult::kFailedToPoke);
    } else {
      LOG(ERROR) << "Failed to kill OOP mount helper";
      ReportOOPMountCleanupResult(OOPMountCleanupResult::kFailedToKill);
    }
  }

  // Reset the brillo::Process object to close pipe file descriptors.
  helper_process_->Reset(0);
}

bool OutOfProcessMountHelper::PerformEphemeralMount(
    const std::string& username) {
  OutOfProcessMountRequest request;
  request.set_username(username);
  request.set_system_salt(SecureBlobToSecureHex(system_salt_).to_string());
  request.set_legacy_home(legacy_home_);
  request.set_bind_mount_downloads(bind_mount_downloads_);
  request.set_mount_namespace_path(
      chrome_mnt_ns_ && username == brillo::cryptohome::home::kGuestUserName
          ? chrome_mnt_ns_->path().value()
          : "");
  request.set_type(cryptohome::OutOfProcessMountRequest_MountType_EPHEMERAL);

  OutOfProcessMountResponse response;
  if (!LaunchOutOfProcessHelper(request, &response)) {
    return false;
  }

  username_ = request.username();
  if (response.paths_size() > 0) {
    for (int i = 0; i < response.paths_size(); i++) {
      mounted_paths_.insert(response.paths(i));
    }
  }

  return true;
}

bool OutOfProcessMountHelper::LaunchOutOfProcessHelper(
    const OutOfProcessMountRequest& request,
    OutOfProcessMountResponse* response) {
  std::unique_ptr<brillo::Process> mount_helper =
      platform_->CreateProcessInstance();

  mount_helper->AddArg("/usr/sbin/cryptohome-namespace-mounter");

  mount_helper->RedirectUsingPipe(
      STDIN_FILENO, true /* is_input, from child's perspective */);
  mount_helper->RedirectUsingPipe(
      STDOUT_FILENO, false /* is_input, from child's perspective */);

  ReportTimerStart(kOOPMountOperationTimer);

  if (!mount_helper->Start()) {
    LOG(ERROR) << "Failed to start OOP mount helper";
    ReportOOPMountOperationResult(OOPMountOperationResult::kFailedToStart);
    return false;
  }

  helper_process_ = std::move(mount_helper);
  write_to_helper_ = helper_process_->GetPipe(STDIN_FILENO);
  int read_from_helper = helper_process_->GetPipe(STDOUT_FILENO);

  base::ScopedClosureRunner kill_runner(
      base::Bind(&OutOfProcessMountHelper::KillOutOfProcessHelperIfNecessary,
                 base::Unretained(this)));

  if (!WriteProtobuf(write_to_helper_, request)) {
    LOG(ERROR) << "Failed to write request protobuf";
    ReportOOPMountOperationResult(
        OOPMountOperationResult::kFailedToWriteRequestProtobuf);
    return false;
  }

  // Avoid blocking forever in the read(2) call below by poll(2)-ing the file
  // descriptor with a |kOutOfProcessHelperMountTimeout| long timeout.
  if (!WaitForHelper(read_from_helper, kOutOfProcessHelperMountTimeout)) {
    LOG(ERROR) << "OOP mount helper did not respond in time";
    ReportOOPMountOperationResult(
        OOPMountOperationResult::kHelperProcessTimedOut);
    return false;
  }

  if (!ReadProtobuf(read_from_helper, response)) {
    LOG(ERROR) << "Failed to read response protobuf";
    ReportOOPMountOperationResult(
        OOPMountOperationResult::kFailedToReadResponseProtobuf);
    return false;
  }

  // OOP mount helper started successfully, report elapsed time since process
  // was started.
  ReportTimerStop(kOOPMountOperationTimer);

  // OOP mount helper started successfully, release the clean-up closure.
  ignore_result(kill_runner.Release());

  LOG(INFO) << "OOP mount helper started successfully";
  ReportOOPMountOperationResult(OOPMountOperationResult::kSuccess);
  return true;
}

bool OutOfProcessMountHelper::TearDownEphemeralMount() {
  return TearDownExistingMount();
}

void OutOfProcessMountHelper::TearDownNonEphemeralMount() {
  TearDownExistingMount();
}

bool OutOfProcessMountHelper::TearDownExistingMount() {
  if (!helper_process_) {
    LOG(WARNING) << "Can't tear down mount, OOP mount helper is not running";
    return false;
  }

  // While currently a MountHelper instance is not used for more than one
  // cryptohome mount operation, this function should ensure that the
  // MountHelper instance is left in a state suited to perform subsequent
  // mounts.
  KillOutOfProcessHelperIfNecessary();
  mounted_paths_.clear();
  username_.clear();
  return true;
}

bool OutOfProcessMountHelper::PerformMount(const Options& mount_opts,
                                           const std::string& username,
                                           const std::string& fek_signature,
                                           const std::string& fnek_signature,
                                           bool is_pristine,
                                           MountError* error) {
  OutOfProcessMountRequest request;
  request.set_username(username);
  request.set_system_salt(SecureBlobToSecureHex(system_salt_).to_string());
  request.set_bind_mount_downloads(bind_mount_downloads_);
  request.set_legacy_home(legacy_home_);
  request.set_mount_namespace_path(chrome_mnt_ns_ && IsolateUserSession()
                                       ? chrome_mnt_ns_->path().value()
                                       : "");
  request.set_type(mount_type[mount_opts.type]);
  request.set_to_migrate_from_ecryptfs(mount_opts.to_migrate_from_ecryptfs);
  request.set_fek_signature(fek_signature);
  request.set_fnek_signature(fnek_signature);
  request.set_is_pristine(is_pristine);

  OutOfProcessMountResponse response;
  if (!LaunchOutOfProcessHelper(request, &response)) {
    return false;
  }

  username_ = request.username();
  if (response.paths_size() > 0) {
    for (int i = 0; i < response.paths_size(); i++) {
      mounted_paths_.insert(response.paths(i));
    }
  }

  *error = static_cast<MountError>(response.mount_error());
  return true;
}

}  // namespace cryptohome
