// 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 "imageloader/verity_mounter.h"

#include <algorithm>
#include <memory>
#include <utility>

#include </usr/include/linux/magic.h>
#include <fcntl.h>
#include <libdevmapper.h>
#include <linux/loop.h>
#include <mntent.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/vfs.h>

#include <base/command_line.h>
#include <base/containers/adapters.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/process/launch.h>
#include <base/rand_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>

#include "imageloader/component.h"
#include "imageloader/verity_mounter_impl.h"

namespace imageloader {

namespace {
// Path to devices created by device mapper.
constexpr char kDeviceMapperPath[] = "/dev/mapper";

using dm_task_ptr = std::unique_ptr<dm_task, void(*)(dm_task *)>;

enum class MountStatus { FAIL, RETRY, SUCCESS };

constexpr int GET_LOOP_DEVICE_MAX_RETRY = 5;
constexpr int DMSETUP_TIMEOUT_SECONDS = 3;

// Fetches the device mapper table entry with the specified name and writes the
// type and parameters into the provided pointers.
// Returns true on success.
bool MapperGetEntry(const std::string& name, std::string* type,
                    std::string* parameters) {
  auto task = dm_task_ptr(dm_task_create(DM_DEVICE_TABLE), &dm_task_destroy);
  struct dm_info info;

  if (!task) {
    LOG(ERROR) << "dm_task_create failed!";
    return false;
  }

  if (!dm_task_set_name(task.get(), name.c_str())) {
    LOG(ERROR) << "dm_task_set_name failed!";
    return false;
  }

  if (!dm_task_run(task.get())) {
    LOG(ERROR) << "dm_task_run failed!";
    return false;
  }

  if (!dm_task_get_info(task.get(), &info)) {
    LOG(ERROR) << "dm_task_get_info failed!";
    return false;
  }

  void* next = nullptr;
  uint64_t start;
  uint64_t length;
  char* type_cstr;
  char* parameters_cstr;
  next = dm_get_next_target(task.get(), next, &start, &length, &type_cstr,
                            &parameters_cstr);
  if (type != nullptr) {
    *type = std::string(type_cstr);
  }
  if (parameters != nullptr) {
    *parameters = std::string(parameters_cstr);
  }
  return true;
}

// Fetches the length of the device mapper table entries for the specified name.
bool MapperTableLength(const std::string& name, uint64_t* length) {
  auto task = dm_task_ptr(dm_task_create(DM_DEVICE_TABLE), &dm_task_destroy);
  struct dm_info info;

  if (!task) {
    LOG(ERROR) << "dm_task_create failed!";
    return false;
  }

  if (!dm_task_set_name(task.get(), name.c_str())) {
    LOG(ERROR) << "dm_task_set_name failed!";
    return false;
  }

  if (!dm_task_run(task.get())) {
    LOG(ERROR) << "dm_task_run failed!";
    return false;
  }

  if (!dm_task_get_info(task.get(), &info)) {
    LOG(ERROR) << "dm_task_get_info failed!";
    return false;
  }

  *length = 0;
  void* next = nullptr;
  uint64_t start;
  uint64_t length_part;
  char* type;
  char* parameters;
  do {
    next =
        dm_get_next_target(task.get(), next, &start, &length_part, &type,
                           &parameters);
    *length += length_part;
  } while (next);
  return true;
}

// Executes the equivalent of: dmsetup wipe_table <name>
// Returns true on success.
bool MapperWipeTable(const std::string& name) {
  uint64_t length;
  if (!MapperTableLength(name, &length)) {
    return false;
  }

  auto task = dm_task_ptr(dm_task_create(DM_DEVICE_RELOAD), &dm_task_destroy);

  if (!task) {
    LOG(ERROR) << "dm_task_create failed!";
    return false;
  }

  if (!dm_task_set_name(task.get(), name.c_str())) {
    LOG(ERROR) << "dm_task_set_name failed!";
    return false;
  }

  if (!dm_task_add_target(task.get(), 0, length, "error", "")) {
    LOG(ERROR) << "dm_task_add_target failed!";
    return false;
  }

  if (!dm_task_run(task.get())) {
    LOG(ERROR) << "dm_task_run failed!";
    return false;
  }
  return true;
}

// Executes the equivalent of: dmsetup remove <name>
// Returns true on success.
bool MapperRemove(const std::string& name) {
  auto task = dm_task_ptr(dm_task_create(DM_DEVICE_REMOVE), &dm_task_destroy);

  if (!task) {
    LOG(ERROR) << "dm_task_create failed!";
    return false;
  }

  if (!dm_task_set_name(task.get(), name.c_str())) {
    LOG(ERROR) << "dm_task_set_name failed!";
    return false;
  }

  if (!dm_task_run(task.get())) {
    LOG(ERROR) << "dm_task_run failed!";
    return false;
  }
  return true;
}

// |argv| should include all the commands and table to dmsetup, but not
// include the path to the binary.
bool RunDMSetup(const std::vector<std::string>& argv) {
  base::LaunchOptions options;
  options.clear_environ = true;

  std::vector<std::string> full_argv(argv);
  full_argv.insert(full_argv.begin(), "/sbin/dmsetup");

  base::Process process = base::LaunchProcess(full_argv, options);

  if (!process.IsValid()) {
    LOG(ERROR) << "Failed to launch dmsetup process";
    return false;
  }

  int exit_code;
  if (!process.WaitForExitWithTimeout(
          base::TimeDelta::FromSeconds(DMSETUP_TIMEOUT_SECONDS), &exit_code)) {
    LOG(ERROR) << "Failed to wait for dmsetup process.";
    return false;
  }

  return exit_code == 0;
}

bool LaunchDMCreate(const std::string& name, const std::string& table) {
  const std::vector<std::string> argv = {"create", name, "--table",
                                         table.c_str(), "--readonly"};
  return RunDMSetup(argv);
}

// Clear the /dev/mapper/<foo> verity device.
void ClearVerityDevice(const std::string& name) {
  // Per the man page, wipe_table:
  // Wait for any I/O in-flight through the device to complete, then replace the
  // table with a new table that fails any new I/O sent to the device.  If
  // successful, this should release any devices held open by the device's
  // table(s).
  MapperWipeTable(name);
  // Now remove the actual device.
  MapperRemove(name);
}

// Clear the file descriptor behind a loop device.
void ClearLoopDevice(const std::string& device_path) {
  base::ScopedFD loop_device_fd(
      open(device_path.c_str(), O_RDONLY | O_CLOEXEC));
  if (loop_device_fd.is_valid()) ioctl(loop_device_fd.get(), LOOP_CLR_FD, 0);
}

bool SetupDeviceMapper(const std::string& device_path, const std::string& table,
                       std::string* dev_name) {
  // Now setup the dmsetup table.
  std::string final_table = table;
  if (!VerityMounter::SetupTable(&final_table, device_path)) return false;

  // Generate a name with a random string of 32 characters: we consider this to
  // have sufficiently low chance of collision to assume the name isn't taken.
  std::vector<uint8_t> rand_bytes(32);
  base::RandBytes(rand_bytes.data(), rand_bytes.size());
  std::string name = base::HexEncode(rand_bytes.data(), rand_bytes.size());

  if (!LaunchDMCreate(name, final_table)) {
    LOG(ERROR) << "Failed to run dmsetup.";
    return false;
  }

  const base::FilePath dev_mapper(kDeviceMapperPath);
  dev_name->assign(dev_mapper.Append(name).value().c_str());
  return true;
}

bool CreateDirectoryWithMode(const base::FilePath& full_path, int mode) {
  std::vector<base::FilePath> subpaths;

  // Collect a list of all parent directories.
  base::FilePath last_path = full_path;
  subpaths.push_back(full_path);
  for (base::FilePath path = full_path.DirName();
       path.value() != last_path.value(); path = path.DirName()) {
    subpaths.push_back(path);
    last_path = path;
  }

  // Iterate through the parents and create the missing ones.
  for (const auto& subpath : base::Reversed(subpaths)) {
    if (base::DirectoryExists(subpath)) continue;
    if (mkdir(subpath.value().c_str(), mode) == 0) continue;
    // Mkdir failed, but it might have failed with EEXIST, or some other error
    // due to the directory appearing out of thin air. This can occur if two
    // processes are trying to create the same file system tree at the same
    // time. Check to see if it exists and make sure it is a directory.
    if (!base::DirectoryExists(subpath)) {
      PLOG(ERROR) << "Failed to create directory: " << subpath.value();
      return false;
    }
  }
  return true;
}

bool CreateMountPointIfNeeded(const base::FilePath& mount_point,
                              bool* already_mounted) {
  *already_mounted = false;
  // Is this mount point somehow already taken?
  struct stat st;
  if (lstat(mount_point.value().c_str(), &st) == 0) {
    if (!S_ISDIR(st.st_mode)) {
      LOG(ERROR) << "Mount point exists but is not a directory.";
      return false;
    }

    base::FilePath mount_parent = mount_point.DirName();
    struct stat st2;
    if (stat(mount_parent.value().c_str(), &st2) != 0) {
      PLOG(ERROR) << "Could not stat the mount point parent";
      return false;
    }
    if (st.st_dev != st2.st_dev) {
      struct statfs st_fs;
      if (statfs(mount_point.value().c_str(), &st_fs) != 0) {
        PLOG(ERROR) << "statfs";
        return false;
      }
      if ((st_fs.f_type != SQUASHFS_MAGIC && st_fs.f_type != EXT4_SUPER_MAGIC)
          || !(st_fs.f_flags & ST_NODEV)
          || !(st_fs.f_flags & ST_NOSUID)
          || !(st_fs.f_flags & ST_RDONLY)) {
        LOG(ERROR) << "File system is not the expected type.";
        return false;
      }
      *already_mounted = true;
      return true;
    }
  } else if (!CreateDirectoryWithMode(mount_point, kComponentDirPerms)) {
    LOG(ERROR) << "Failed to create mount point: " << mount_point.value();
    return false;
  }
  return true;
}

// Reserves a loop device and associates it with |image_fd|. The path to the
// loop device is returned in |device_path_out|. When the loop device is no
// longer being used, free the resource with ClearLoopDevice().
MountStatus GetLoopDevice(const base::ScopedFD& image_fd,
                          std::string* device_path_out) {
  base::ScopedFD loopctl_fd(open("/dev/loop-control", O_RDONLY | O_CLOEXEC));
  if (!loopctl_fd.is_valid()) {
    PLOG(ERROR) << "loopctl_fd";
    return MountStatus::FAIL;
  }
  int device_free_number = ioctl(loopctl_fd.get(), LOOP_CTL_GET_FREE);
  if (device_free_number < 0) {
    PLOG(ERROR) << "ioctl : LOOP_CTL_GET_FREE";
    return MountStatus::FAIL;
  }

  std::string device_path =
      base::StringPrintf("/dev/loop%d", device_free_number);
  base::ScopedFD loop_device_fd(
      open(device_path.c_str(), O_RDONLY | O_CLOEXEC));
  if (!loop_device_fd.is_valid()) {
    PLOG(ERROR) << "Failed to open loop device: " << device_path;
    return MountStatus::FAIL;
  }

  if (ioctl(loop_device_fd.get(), LOOP_SET_FD, image_fd.get()) == -1) {
    if (errno != EBUSY) {
      PLOG(ERROR) << "ioctl: LOOP_SET_FD";
      ioctl(loop_device_fd.get(), LOOP_CLR_FD, 0);
      return MountStatus::FAIL;
    }
    return MountStatus::RETRY;
  }

  device_path_out->assign(device_path);
  return MountStatus::SUCCESS;
}

}  // namespace

// static
bool VerityMounter::SetupTable(std::string* table,
                               const std::string& device_path) {
  // Make sure there is only one entry in the device mapper table.
  if (std::count(table->begin(), table->end(), '\n') > 1) return false;

  // Remove all newlines from the table. This is to workaround the server
  // incorrectly inserting a newline when writing out the table.
  table->erase(std::remove(table->begin(), table->end(), '\n'), table->end());
  // Replace in the actual loop device name.
  base::ReplaceSubstringsAfterOffset(table, 0, "ROOT_DEV", device_path);
  base::ReplaceSubstringsAfterOffset(table, 0, "HASH_DEV", device_path);
  // If the table does not specify an error condition, use the default (eio).
  // This is critical because the default behavior is to panic the device and
  // force a system recovery. Do not do this for component corruption.
  if (table->find("error_behavior") == std::string::npos)
    table->append(" error_behavior=eio");

  return true;
}

bool VerityMounter::Mount(const base::ScopedFD& image_fd,
                          const base::FilePath& mount_point,
                          const std::string& fs_type,
                          const std::string& table) {
  // First check if the component is already mounted and avoid unnecessary work.
  bool already_mounted = false;
  if (!CreateMountPointIfNeeded(mount_point, &already_mounted)) return false;
  if (already_mounted) return true;

  std::string loop_device_path;
  // We need to retry because another program could grap the loop device,
  // resulting in an EBUSY error. If that happens, run again and grab a new
  // device.
  int retries = GET_LOOP_DEVICE_MAX_RETRY;
  while (true) {
    MountStatus status = GetLoopDevice(image_fd, &loop_device_path);
    if (status == MountStatus::FAIL ||
        (status == MountStatus::RETRY && retries == 0)) {
      LOG(ERROR) << "GetLoopDevice failed, mount_point: "
                 << mount_point.value();
      return false;
    } else if (status == MountStatus::SUCCESS) {
      break;
    }
    --retries;
  }

  std::string dev_name;
  if (!SetupDeviceMapper(loop_device_path, table, &dev_name)) {
    LOG(ERROR) << "mount_point: " << mount_point.value();
    ClearLoopDevice(loop_device_path);
    return false;
  }

  if (mount(dev_name.c_str(), mount_point.value().c_str(), fs_type.c_str(),
            MS_RDONLY | MS_NOSUID | MS_NODEV, "") < 0) {
    PLOG(ERROR) << "mount, mount_point " << mount_point.value();
    ClearVerityDevice(dev_name);
    ClearLoopDevice(loop_device_path);
    return false;
  }

  return true;
}

// Takes a device mapper name and determines the loop device number.
bool MapperNameToLoop(const std::string& name, int32_t* loop) {
  std::string type;
  std::string parameters;
  if (!MapperGetEntry(name, &type, &parameters)) {
    return false;
  }

  if (type != "verity") {
    LOG(ERROR) << "Encountered unexpected mapping \"" << type
               << "\" instead of \"verity\".";
    return false;
  }

  return MapperParametersToLoop(parameters, loop);
}

bool Unmount(const base::FilePath& mount_point) {
  return umount(mount_point.value().c_str()) == 0;
}

// Returns (mount point, source path) pairs visible to this process. The order
// can be reversed to help with unmounting.
std::vector<std::pair<std::string, std::string>>
    GetAllMountPaths(bool reverse) {
  std::vector<std::pair<std::string, std::string>> mount_paths;
  base::ScopedFILE mountinfo(fopen("/proc/self/mounts", "re"));
  if (!mountinfo) {
    PLOG(ERROR) << "Failed to open \"/proc/self/mounts\".";
    return mount_paths;
  }

  // MNT_LINE_MAX from sys/mnttab.h is 1024, extra bytes are for null
  // termination of strings.
  static char buffer[1024 + 4];
  struct mntent mount_entry;
  while (getmntent_r(mountinfo.get(), &mount_entry, buffer, sizeof(buffer))) {
    mount_paths.emplace(reverse ? mount_paths.end() : mount_paths.begin(),
                        mount_entry.mnt_dir, mount_entry.mnt_fsname);
  }
  return mount_paths;
}

// Performs the a cleanup of a given mount point which should be tied to the
// given source path. This entails unmounting the mount point, removing the
// device mapper table entry, deleting the mount point folder, and freeing the
// loop device.
// Returns true on success.
bool CleanupImpl(const base::FilePath& mount_point,
                 const base::FilePath source_path) {
  const base::FilePath dev_mapper(kDeviceMapperPath);
  if (!IsAncestor(dev_mapper, source_path)) {
    LOG(ERROR) << source_path.value() << " is not device mapped!";
    return false;
  }

  // Lookup loop info.
  int32_t loop = -1;
  if (!MapperNameToLoop(source_path.BaseName().value(), &loop) ||
      loop < 0) {
    LOG(ERROR) << "Unable to determine loop device for " << source_path.value();
    return false;
  }

  // Unmount the image.
  if (!Unmount(mount_point)) {
    PLOG(ERROR) << "Unmount failed";
    return false;
  }
  // Delete mount target folder
  base::DeleteFile(mount_point, true);

  // Clear Verity device.
  if (!MapperWipeTable(source_path.value())) {
    PLOG(ERROR) << "Device mapper wipe table failed";
    return false;
  }
  if (!MapperRemove(source_path.value())) {
    PLOG(ERROR) << "Device mapper remove failed";
    return false;
  }

  // Clear loop device.
  ClearLoopDevice(base::StringPrintf("/dev/loop%d", loop));
  return true;
}

// Unmounts the given path, cleans up the device mapper entry, and frees the
// loop device for the specified mount point.
// Returns true on success.
bool VerityMounter::Cleanup(const base::FilePath& mount_point) {
  bool ret = true;
  for (const auto& mount_path : GetAllMountPaths(true)) {
    if (mount_point.value() == mount_path.first) {
      if (!CleanupImpl(mount_point, base::FilePath(mount_path.second))) {
        ret = false;
      }
    }
  }
  return ret;
}

// Performs a cleanup for all mount points under parent_dir.
// All successfully cleaned up mount points will be appended to "paths".
// Returns false if cleanup fails for any mount point.
bool VerityMounter::CleanupAll(bool dry_run,
                               const base::FilePath& parent_dir,
                               std::vector<base::FilePath>* paths) {
  bool ret = true;
  for (const auto& mount_path : GetAllMountPaths(true)) {
    base::FilePath fp_mount_path(mount_path.first);
    // It is not enough to check if fp_mount_path is a direct child because
    // some mount points, such as printer drivers, are mounted under a sub
    // folder.
    if (IsAncestor(parent_dir, fp_mount_path)) {
      if (dry_run) {
        if (paths) {
          paths->push_back(fp_mount_path);
        }
      } else if (CleanupImpl(fp_mount_path,
                             base::FilePath(mount_path.second))) {
        if (paths) {
          paths->push_back(fp_mount_path);
        }
      } else {
        LOG(ERROR) << "Failed to cleanup \"" << mount_path.first << "\"";
        ret = false;
      }
    }
  }
  return ret;
}

}  // namespace imageloader
