// 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 "crash-reporter/core-collector/coredump_writer.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sysexits.h>
#include <unistd.h>

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <string>

#include <common/linux/elf_core_dump.h>

#include "crash-reporter/core-collector/logging.h"

using google_breakpad::ElfCoreDump;

namespace {

const size_t kMaxAbsCoredumpSize = 256 * 1024 * 1024;
const double kMaxRelCoredumpSize = 0.05;  // Percentage of free disk space.

struct ScopedFd {
  explicit ScopedFd(int fd) : fd(fd) {}
  ~ScopedFd() { close(fd); }

  bool IsValid() const { return fd >= 0; }
  operator int() const { return fd; }

  const int fd;
};

template <typename DataPtr>
using FdFunctionPtr = ssize_t (*)(int, DataPtr, size_t);

// Reads or writes exactly |count| bytes of |data| using |fd| as the source or
// destination, respectively.
template <typename DataPtr, typename BytePtr, FdFunctionPtr<DataPtr> op>
struct FdOperation {
  bool operator()(int fd, DataPtr data, size_t count) {
    BytePtr ptr = reinterpret_cast<BytePtr>(data);
    while (count > 0) {
      const ssize_t n = TEMP_FAILURE_RETRY(op(fd, ptr, count));
      if (n < 0)
        return false;
      if (n == 0) {
        errno = EIO;
        return false;
      }
      ptr += n;
      count -= n;
    }
    return true;
  }
};

FdOperation<void*, uint8_t*, &read> ReadAllBlocking;
FdOperation<const void*, const uint8_t*, &write> WriteAllBlocking;

inline bool Seek(int fd, off_t offset) {
  return lseek(fd, offset, SEEK_SET) == offset;
}

inline int64_t GetFreeDiskSpace(const char* path) {
  struct statvfs stats;
  return TEMP_FAILURE_RETRY(statvfs(path, &stats)) != 0
             ? -1
             : static_cast<int64_t>(stats.f_bavail) * stats.f_frsize;
}

}  // namespace

class CoredumpWriter::Reader {
 public:
  explicit Reader(int fd) : fd_(fd) {}
  Reader(const Reader&) = delete;
  Reader& operator=(const Reader&) = delete;

  bool Read(void* buf, size_t count) {
    if (!ReadAllBlocking(fd_, buf, count))
      return false;
    bytes_read_ += count;
    return true;
  }

  bool CopyTo(int dest_fd, size_t count) {
    static const size_t kBufSize = 32 * 1024;
    char buf[kBufSize];
    while (count > 0) {
      const ssize_t n =
          TEMP_FAILURE_RETRY(read(fd_, buf, std::min(kBufSize, count)));
      if (n < 0)
        return false;
      if (n == 0) {
        errno = 0;
        break;
      }
      if (dest_fd >= 0 && !WriteAllBlocking(dest_fd, buf, n))
        return false;
      count -= n;
      bytes_read_ += n;
    }
    return count == 0;
  }

  bool Seek(size_t offset) {
    if (offset < bytes_read_)  // Cannot move backward.
      return false;
    return CopyTo(-1, offset - bytes_read_);
  }

 private:
  const int fd_;
  size_t bytes_read_ = 0;
};

CoredumpWriter::CoredumpWriter(int fd,
                               const char* coredump_path,
                               const char* container_dir)
    : fd_(fd), coredump_path_(coredump_path), container_dir_(container_dir) {}

int CoredumpWriter::WriteCoredump() {
  const ScopedFd dest(TEMP_FAILURE_RETRY(
      open(coredump_path_, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)));

  if (!dest.IsValid()) {
    PLOG_ERROR << "Failed to open '" << coredump_path_ << "'";
    return EX_CANTCREAT;
  }

  // Input core dump is generated by kernel's fs/binfmt_elf.c using this format:
  //
  //   ELF Header
  //   Program Header 1
  //   Program Header 2
  //   ...
  //   Program Header n
  //   Segment 1 (This segment's type should be PT_NOTE)
  //   Segment 2
  //   ...
  //   Segment n

  // Read ELF header, all program headers, and the first segment whose type is
  // PT_NOTE.
  Reader reader(fd_);
  Ehdr elf_header;
  std::vector<Phdr> program_headers;
  std::vector<char> note_buf;
  int error = ReadUntilNote(&reader, &elf_header, &program_headers, &note_buf);
  if (error != EX_OK)
    return error;

  // Get a set of address ranges occupied by mapped files from PT_NOTE segment.
  FileMappings file_mappings;
  if (!GetFileMappings(note_buf, &file_mappings))
    return EX_OSFILE;

  // Strip segments backed by mapped files, since they are not needed to
  // generate a minidump.
  std::vector<Phdr> stripped_program_headers;
  StripSegments(program_headers, file_mappings, &stripped_program_headers);

  // Calculate the core dump size limit.
  const int64_t free_disk_space = GetFreeDiskSpace(coredump_path_);
  if (free_disk_space < 0) {
    PLOG_ERROR << "Failed to get free disk space";
    return EX_OSERR;
  }
  const auto coredump_size_limit =
      std::min(kMaxAbsCoredumpSize,
               static_cast<size_t>(free_disk_space * kMaxRelCoredumpSize));

  // Calculate the output file size.
  const auto& last = stripped_program_headers.back();
  const auto expected_coredump_size = last.p_offset + last.p_filesz;
  if (expected_coredump_size > coredump_size_limit) {
    LOG_ERROR << "Exceeded maximum core dump size by "
              << expected_coredump_size - coredump_size_limit << " bytes";
    return EX_CANTCREAT;
  }

  // Write /proc files.
  error = WriteAuxv(note_buf);
  if (error != EX_OK) {
    LOG_ERROR << "Failed to write auxv";
    return error;
  }
  error = WriteMaps(program_headers, file_mappings);
  if (error != EX_OK) {
    LOG_ERROR << "Failed to write maps";
    return error;
  }

  // Write ELF header.
  if (!WriteAllBlocking(dest, &elf_header, sizeof(elf_header))) {
    PLOG_ERROR << "Failed to write ELF header";
    return EX_IOERR;
  }

  // Write program headers.
  for (size_t i = 0; i < stripped_program_headers.size(); ++i) {
    const Phdr& program_header = stripped_program_headers[i];
    const auto offset = sizeof(elf_header) + i * elf_header.e_phentsize;
    if (!Seek(dest, offset) ||
        !WriteAllBlocking(dest, &program_header, sizeof(program_header))) {
      PLOG_ERROR << "Failed to write program header";
      return EX_IOERR;
    }
  }

  // Write PT_NOTE segment.
  if (!Seek(dest, stripped_program_headers[0].p_offset) ||
      !WriteAllBlocking(dest, note_buf.data(), note_buf.size())) {
    PLOG_ERROR << "Failed to write PT_NOTE segment";
    return EX_IOERR;
  }

  // Write segments that were not stripped.
  for (size_t i = 1; i < stripped_program_headers.size(); ++i) {
    const Phdr& program_header = stripped_program_headers[i];
    if (program_header.p_filesz == 0)
      continue;
    const Phdr& program_header_original = program_headers[i];
    if (!reader.Seek(program_header_original.p_offset)) {
      PLOG_ERROR << "Failed to seek segment";
      return EX_IOERR;
    }
    if (!Seek(dest, program_header.p_offset) ||
        !reader.CopyTo(dest, program_header.p_filesz)) {
      PLOG_ERROR << "Failed to write segment";
      return EX_IOERR;
    }
  }

  return EX_OK;
}

int CoredumpWriter::ReadUntilNote(Reader* reader,
                                  Ehdr* elf_header,
                                  std::vector<Phdr>* program_headers,
                                  std::vector<char>* note_buf) {
  // Read ELF header.
  if (!reader->Read(elf_header, sizeof(*elf_header))) {
    PLOG_ERROR << "Failed to read ELF header";
    return EX_IOERR;
  }
  if (memcmp(elf_header->e_ident, ELFMAG, SELFMAG) != 0 ||
      elf_header->e_ident[EI_CLASS] != ElfCoreDump::kClass ||
      elf_header->e_version != EV_CURRENT || elf_header->e_type != ET_CORE ||
      elf_header->e_ehsize != sizeof(Ehdr) ||
      elf_header->e_phentsize != sizeof(Phdr)) {
    LOG_ERROR << "Invalid ELF header";
    return EX_OSFILE;
  }

  // Read program headers.
  program_headers->resize(elf_header->e_phnum);
  if (!reader->Seek(elf_header->e_phoff) ||
      !reader->Read(program_headers->data(),
                    sizeof(Phdr) * program_headers->size())) {
    PLOG_ERROR << "Failed to read program headers";
    return EX_IOERR;
  }

  // The first segment should have type PT_NOTE. This assumption hinges on the
  // kernel's fs/binfmt_elf.c implementation.
  if (program_headers->empty() || (*program_headers)[0].p_type != PT_NOTE) {
    LOG_ERROR << "Failed to locate PT_NOTE segment";
    return EX_OSFILE;
  }
  const Phdr& note_program_header = (*program_headers)[0];

  // Read PT_NOTE segment.
  note_buf->resize(note_program_header.p_filesz);
  if (!reader->Seek(note_program_header.p_offset) ||
      !reader->Read(note_buf->data(), note_buf->size())) {
    PLOG_ERROR << "Failed to read PT_NOTE segment";
    return EX_IOERR;
  }

  return EX_OK;
}

bool CoredumpWriter::GetFileMappings(const std::vector<char>& note_buf,
                                     FileMappings* file_mappings) {
  // Locate NT_FILE note.
  ElfCoreDump::Note note({note_buf.data(), note_buf.size()});
  while (note.IsValid() && note.GetType() != NT_FILE)
    note = note.GetNextNote();

  if (!note.IsValid()) {
    LOG_ERROR << "Failed to locate NT_FILE note";
    return false;
  }
  const auto note_desc = note.GetDescription();

  // The NT_FILE note is generated by the kernel's fs/binfmt_elf.c as a
  // sequence of long values, followed by a sequence of char values.
  struct FileNote {
    ElfW(Off) count;
    ElfW(Off) page_size;

    struct {
      ElfW(Addr) start;
      ElfW(Addr) end;
      ElfW(Off) offset;
    } files[1];

    // The |files| array has |count| elements. The file paths are stored after
    // the array, as |count| null-terminated strings.
  };
  const FileNote* file_note =
      reinterpret_cast<const FileNote*>(note_desc.data());
  const size_t num_files = file_note->count;
  const char* path =
      reinterpret_cast<const char*>(&file_note->files[num_files]);

  // Populate file mappings.
  for (size_t i = 0; i < num_files; ++i) {
    const auto file = &file_note->files[i];
    const auto it =
        file_mappings->insert({FileRange(file->start, file->end),
                               {file->offset * file_note->page_size, path}});
    // Skip past NUL to next path.
    path += it.first->second.path.length() + 1;
  }
  // The last path should end the note.
  if (path != reinterpret_cast<const char*>(file_note) + note_desc.length()) {
    LOG_ERROR << "Invalid NT_FILE note";
    return false;
  }
  return true;
}

void CoredumpWriter::StripSegments(
    const std::vector<Phdr>& program_headers,
    const FileMappings& file_mappings,
    std::vector<Phdr>* stripped_program_headers) {
  stripped_program_headers->resize(program_headers.size());

  // The first segment has type PT_NOTE. Use the original data unchanged.
  (*stripped_program_headers)[0] = program_headers[0];

  for (size_t i = 1; i < program_headers.size(); ++i) {
    Phdr& out = (*stripped_program_headers)[i];
    out = program_headers[i];

    // If the type is PT_LOAD and the range is found in the set, the segment is
    // backed by a file, so it can be excluded as it doesn't contain stack data
    // useful to generate a minidump.
    const FileRange range(out.p_vaddr, out.p_vaddr + out.p_memsz);
    if (out.p_type == PT_LOAD && file_mappings.count(range))
      out.p_filesz = 0;

    // Calculate offset.
    const Phdr& prev_program_header = (*stripped_program_headers)[i - 1];
    out.p_offset = prev_program_header.p_offset + prev_program_header.p_filesz;
    // Offset alignment.
    if (out.p_align != 0 && out.p_offset % out.p_align != 0)
      out.p_offset += out.p_align - out.p_offset % out.p_align;
  }
}

int CoredumpWriter::WriteAuxv(const std::vector<char>& note_buf) {
  // Locate NT_AUXV note.
  ElfCoreDump::Note note({note_buf.data(), note_buf.size()});
  while (note.IsValid() && note.GetType() != NT_AUXV)
    note = note.GetNextNote();

  if (!note.IsValid()) {
    LOG_ERROR << "Failed to locate NT_AUXV note";
    return EX_OSFILE;
  }

  const auto path = container_dir_ + std::string("/auxv");
  const ScopedFd auxv(TEMP_FAILURE_RETRY(
      open(path.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)));

  if (!auxv.IsValid()) {
    PLOG_ERROR << "Failed to open '" << path.c_str() << "'";
    return EX_CANTCREAT;
  }

  // The NT_AUXV note has the same format as /proc/[pid]/auxv.
  const auto desc = note.GetDescription();
  return WriteAllBlocking(auxv, desc.data(), desc.length()) ? EX_OK : EX_IOERR;
}

int CoredumpWriter::WriteMaps(const std::vector<Phdr>& program_headers,
                              const FileMappings& file_mappings) {
  const auto path = container_dir_ + std::string("/maps");
  const ScopedFd maps(TEMP_FAILURE_RETRY(
      open(path.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)));

  if (!maps.IsValid()) {
    PLOG_ERROR << "Failed to open '" << path.c_str() << "'";
    return EX_CANTCREAT;
  }

  for (const auto& program_header : program_headers) {
    if (program_header.p_type != PT_LOAD)
      continue;
    const FileRange range(program_header.p_vaddr,
                          program_header.p_vaddr + program_header.p_memsz);
    // If a mapping is found for the range, the range is mapped to a file.
    const auto it = file_mappings.find(range);
    const ElfW(Off) offset = it != file_mappings.end() ? it->second.offset : 0;
    const auto path = it != file_mappings.end() ? it->second.path.c_str() : "";

    const int kBufSize = 1024;
    char buf[kBufSize];
    // See kernel's fs/proc/task_{no,}mmu.c for format string.
    const int len = snprintf(
        buf, kBufSize,
        "%08" PRIxPTR
        "-"
        "%08" PRIxPTR
        " %c%c%c%c"
        " %08" PRIx64 " %02x:%02x %lu %s\n",
        range.first, range.second, program_header.p_flags & PF_R ? 'r' : '-',
        program_header.p_flags & PF_W ? 'w' : '-',
        program_header.p_flags & PF_X ? 'x' : '-',
        'p',  // Fake value: we can't know if the mapping is shared or private.
        static_cast<uint64_t>(offset),
        0,    // Fake device (major) value.
        0,    // Fake device (minor) value.
        0ul,  // Fake inode value.
        path);
    if (len < 0 || len >= kBufSize || !WriteAllBlocking(maps, buf, len))
      return EX_OSFILE;
  }

  return EX_OK;
}
