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

#include <fcntl.h>
#include <linux/fiemap.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/mmc/ioctl.h>
#include <mntent.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/memory/free_deleter.h>
#include <base/memory/ptr_util.h>
#include <base/process/launch.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

namespace secure_erase_file {
namespace {

// A container for fiemap that handles cleaning up allocated memory.
// base::FreeDeleter must be used here because the underlying struct fiemap is
// allocated with malloc().
typedef std::unique_ptr<struct fiemap, base::FreeDeleter> ScopedFiemap;

// For simplicity, we only support files with up to 32 extents, and fail
// otherwise.
//
// This is somewhat arbitrary and could be increased in the future if there is a
// need to securely erase larger files.
constexpr int kMaxExtents = 32;

// When verifying that the original data can not be read back, we read in 1M
// chunks instead of reading the whole file at once.
constexpr size_t kVerifyReadSizeBytes = 1024 * 1024;

const char kMountsPath[] = "/proc/mounts";

// Given a file path, return the corresponding mount entry info in /proc/mount.
// TODO(teravest): This will not work for files on eCryptfs partitions.
// See Platform::FindFilesystemDevice() in cryptohome for logic that would work
// for more paths.
std::string PartitionForPath(const base::FilePath& file_path) {
  std::string partition;

  const std::string path = file_path.value();
  std::unique_ptr<FILE, int (*)(FILE*)> mnts(setmntent(kMountsPath, "re"),
                                             endmntent);
  if (!mnts) {
    PLOG(ERROR) << "Unable to open " << kMountsPath;
    return std::string();
  }

  size_t best_length = 0;
  auto best_mntent = base::MakeUnique<struct mntent>();

  struct mntent* mnt;
  // getmntent() returns a thread local, so it's safe.
  while ((mnt = getmntent(mnts.get())) != nullptr) {
    auto l = strlen(mnt->mnt_dir);
    if (l > best_length && path.size() > l && path[l] == '/' &&
        path.compare(0, l, mnt->mnt_dir) == 0) {
      partition = std::string(mnt->mnt_fsname);
      best_length = l;
    }
  }

  if (best_length == 0) {
    LOG(ERROR) << "Didn't find a partition to match path " << path;
  }
  return partition;
}

// Verifies that the data for an extent has been erased by seeking within the
// partition and confirming that the original file data is erased.
//
// Returns true only if the read succeeds and all bytes are 0x00 or 0xFF.
bool VerifyExtentErased(int partition_fd, uint64_t start, uint64_t len) {
  // NOTE: This verification scheme assumes that blocks can be read after being
  // trimmed. According to gwendal@, this is not true for NVMe 1.3 devices with
  // NSFEAT bit 2 set to 1. If that is something we need to support, we could
  // confirm that the blocks cannot be read on those devices.
  if (lseek(partition_fd, start, SEEK_SET) < 0) {
    PLOG(ERROR) << "Failed to seek in partition fd";
    return false;
  }

  std::unique_ptr<char[]> buf(new char[kVerifyReadSizeBytes]);
  uint64_t to_read = len;
  do {
    // Limit file reads to 1M regions to keep our memory footprint reasonable.
    size_t bytes_to_read = std::min<size_t>(to_read, kVerifyReadSizeBytes);
    int rc = HANDLE_EINTR(read(partition_fd, buf.get(), bytes_to_read));
    if (rc < 0) {
      PLOG(ERROR) << "Failed to read LBAs to verify erase";
      return false;
    }
    for (int i = 0; i < rc; i++) {
      unsigned char ch = buf.get()[i];
      if (ch != 0x00 && ch != 0xFF) {
        LOG(ERROR) << "Found uncleared data at partition byte: "
                   << start + (len - to_read) + i;
        return false;
      }
    }
    to_read -= rc;
  } while (to_read > 0);
  return true;
}

// Fetches extent data for the requested file path.
ScopedFiemap GetExtentsForFile(const base::FilePath& path) {
  size_t alloc_size = offsetof(struct fiemap, fm_extents[kMaxExtents]);
  ScopedFiemap fm(static_cast<struct fiemap*>(malloc(alloc_size)));
  memset(fm.get(), 0, alloc_size);
  fm->fm_length = std::numeric_limits<uint64_t>::max();
  fm->fm_flags |= FIEMAP_FLAG_SYNC;
  fm->fm_extent_count = kMaxExtents;

  base::ScopedFD fd(open(path.value().c_str(), O_RDONLY | O_CLOEXEC));
  if (fd.get() < 0) {
    PLOG(ERROR) << "Unable to open file: " << path.value();
    return nullptr;
  }

  // There's no need to sync() before getting the extents with the ioctl() here;
  // the kernel takes care of that with FIEMAP_FLAG_SYNC set above. See
  // fs/ioctl.c in the kernel for details.
  if (HANDLE_EINTR(ioctl(fd.get(), FS_IOC_FIEMAP, fm.get())) < -1) {
    PLOG(ERROR) << "Unable to get FIEMAP for file: " << path.value();
    return nullptr;
  }

  // We require that the target file has at least 1 extent.
  // This means that we don't support inlined files in ext4, but don't have to
  // handle the case where sensitive data is stored inside the inode.
  if (fm->fm_mapped_extents < 1 || fm->fm_mapped_extents > kMaxExtents) {
    LOG(ERROR) << "Bad number of mapped extents (" << fm->fm_mapped_extents
               << ") for path: " << path.value();
    return nullptr;
  }

  // We don't want to erase data for any files that have shared extents. Doing
  // so may destroy data for other files.
  for (int i = 0; i < fm->fm_mapped_extents; i++) {
    if (fm->fm_extents[i].fe_flags & FIEMAP_EXTENT_SHARED) {
      LOG(ERROR) << "Shared extent found for path: " << path.value();
      return nullptr;
    }
    if (fm->fm_extents[i].fe_flags & FIEMAP_EXTENT_DATA_INLINE) {
      LOG(ERROR) << "Data mixed with metadata in extent found for path: "
                 << path.value();
      return nullptr;
    }
    if (fm->fm_extents[i].fe_flags & FIEMAP_EXTENT_DATA_TAIL) {
      LOG(ERROR) << "Multiple files in block for extent found for path: "
                 << path.value();
      return nullptr;
    }
  }

  return fm;
}

// Trims extents specified in |fm| on the partition specified in |partition_fd|.
bool TrimExtents(int partition_fd, const struct fiemap* fm) {
  for (int i = 0; i < fm->fm_mapped_extents; i++) {
    uint64_t range[2];
    range[0] = fm->fm_extents[i].fe_physical;
    range[1] = fm->fm_extents[i].fe_length;

    // TODO(crbug.com/724169): Explicitly send TRIM+SANITIZE from userspace.
    //
    // BLKDISCARD can't be used as it may send DISCARD instead of a TRIM, which
    // isn't guaranteed to completely remove data with SANITIZE.
    //
    // Similarly, we cannot use FITRIM here because it will skip requests that
    // are smaller than the discard granularity.
    //
    // Sending a TRIM will require either explicitly crafting eMMC commands from
    // userspace, or modifying the kernel to force a TRIM from some other
    // interface.
    //
    // BLKSECDISCARD (Secure Erase) is eMMC-only and is deprecated in favor of
    // TRIM+SANITIZE as of eMMC 4.51.
    if (HANDLE_EINTR(ioctl(partition_fd, BLKSECDISCARD, &range)) < 0) {
      PLOG(ERROR) << "Unable to BLKSECDISCARD target range";
      return false;
    }
  }
  return true;
}

// Verifies that the data in given extents cannot be recovered.
bool VerifyExtentsErased(int partition_fd, const struct fiemap* fm) {
  for (int i = 0; i < fm->fm_mapped_extents; i++) {
    uint64_t range[2];
    range[0] = fm->fm_extents[i].fe_physical;
    range[1] = fm->fm_extents[i].fe_length;

    if (!VerifyExtentErased(partition_fd,
                            fm->fm_extents[i].fe_physical,
                            fm->fm_extents[i].fe_length)) {
      return false;
    }
  }
  return true;
}

}  // namespace

bool IsSupported(const base::FilePath& path) {
  struct stat stat_buf;
  if (stat(path.value().c_str(), &stat_buf) < 0) {
    PLOG(WARNING) << "Could not stat: " << path.value();
    return false;
  }
  if (!S_ISREG(stat_buf.st_mode)) {
    LOG(WARNING) << "File is not a regular file: " << path.value();
    return false;
  }

  // Note that this prevents us from supporting files on mount points like /var.
  // TODO(teravest): Support files that aren't directly mounted.
  if (major(stat_buf.st_dev) != MMC_BLOCK_MAJOR) {
    LOG(WARNING) << "secure_erase_file only supports eMMC devices. "
                 << "Ineligible file: " << path.value();
    return false;
  }

  // TODO(teravest): Send EXT_CSD commands to probe for eMMC command support.
  return true;
}

bool SecureErase(const base::FilePath& path) {
  if (!IsSupported(path)) {
    LOG(ERROR) << "Could not erase file, device unsupported for path: "
               << path.value();
    return false;
  }

  ScopedFiemap fm = GetExtentsForFile(path);
  if (!fm) {
    LOG(ERROR) << "Failed to get extents for file: " << path.value();
    return false;
  }

  std::string partition = PartitionForPath(path);
  if (partition.empty()) {
    LOG(ERROR) << "Partition could not be found for file: " << path.value();
    return false;
  }

  base::ScopedFD partition_fd(
      open(partition.c_str(), O_RDWR | O_LARGEFILE | O_CLOEXEC));
  if (partition_fd.get() < 0) {
    PLOG(ERROR) << "Unable to open partition: " << partition;
  }

  if (!TrimExtents(partition_fd.get(), fm.get())) {
    return false;
  }

  if (!VerifyExtentsErased(partition_fd.get(), fm.get())) {
    return false;
  }

  if (unlink(path.value().c_str()) < 0) {
    PLOG(ERROR) << "Failed to unlink() file: " << path.value();
    return false;
  }
  sync();

  return true;
}

bool DropCaches() {
  // Drop all clean cache data to ensure that erased data does not stay visible.
  // This clears the page cache and slab objects (maybe unnecessary).
  // https://www.kernel.org/doc/Documentation/sysctl/vm.txt
  constexpr char kData[] = "3\n";
  if (!base::WriteFile(
          base::FilePath(FILE_PATH_LITERAL("/proc/sys/vm/drop_caches")),
          kData,
          sizeof(kData))) {
    PLOG(ERROR) << "Failed to drop cache.";
    return false;
  }
  return true;
}

}  // namespace secure_erase_file
