// Copyright 2020 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/vm_support_proper.h"

#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <brillo/key_value_store.h>
#include <chromeos/constants/vm_tools.h>
#include <grpcpp/grpcpp.h>

#include <sys/socket.h>
#include <utility>

#include <linux/vm_sockets.h>

#include "crash-reporter/constants.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/user_collector.h"
#include "crash-reporter/util.h"

namespace {

constexpr char kLsbBoardKey[] = "CHROMEOS_RELEASE_BOARD";
constexpr char kOsNameKey[] = "PRETTY_NAME";
constexpr char kContainerOsReleasePath[] =
    "/mnt/stateful/lxd/storage-pools/default/containers/penguin/rootfs/etc/"
    "os-release";

}  // namespace

class ScopedFileDeleter {
 public:
  explicit ScopedFileDeleter(base::FilePath path) : path_(path) {}
  ~ScopedFileDeleter() {
    if (!base::DeleteFile(path_, false)) {
      LOG(ERROR) << "Failed to delete file " << path_.value();
    }
  }

 private:
  const base::FilePath path_;
};

VmSupportProper::VmSupportProper() {
  std::string addr = base::StringPrintf("vsock:%u:%u", VMADDR_CID_HOST,
                                        vm_tools::kCrashListenerPort);

  // It's safe to use an unencrypted/authenticated channel here because the
  // whole channel exists within a single machine, and so we can rely on the
  // kernel to provide us with confidentiality and integrity. Our usage of a
  // vsock address guarantees this.
  auto channel =
      grpc::CreateChannel(std::move(addr), grpc::InsecureChannelCredentials());
  stub_ = std::make_unique<vm_tools::cicerone::CrashListener::Stub>(
      std::move(channel));
}

void VmSupportProper::AddMetadata(UserCollector* collector) {
  std::string value;
  base::FilePath lsb_path =
      base::FilePath(paths::kEtcDirectory).Append(paths::kLsbRelease);
  util::GetCachedKeyValue(lsb_path.BaseName(), kLsbBoardKey,
                          {lsb_path.DirName()}, &value);
  collector->AddCrashMetaData("board", value);

  base::FilePath os_path = base::FilePath(kContainerOsReleasePath);
  util::GetCachedKeyValue(os_path.BaseName(), kOsNameKey, {os_path.DirName()},
                          &value);
  collector->AddCrashMetaData("upload_var_vm_os_release", value);
}

void VmSupportProper::ProcessFileData(
    const base::FilePath& crash_meta_path,
    const brillo::KeyValueStore& metadata,
    const std::string& key,
    vm_tools::cicerone::CrashReport* crash_report) {
  std::string file_name;
  metadata.GetString(key, &file_name);
  base::FilePath path = crash_meta_path.DirName().Append(file_name);
  ScopedFileDeleter file_deleter(path);

  std::string* dest = nullptr;
  if (key == "payload") {
    dest = crash_report->mutable_minidump();
  } else if (key ==
             std::string(constants::kUploadTextPrefix) + "process_tree") {
    dest = crash_report->mutable_process_tree();
  }
  if (dest && !base::ReadFileToString(path, dest)) {
    LOG(ERROR) << "Failed to read file " << file_name;
  }
}

void VmSupportProper::FinishCrash(const base::FilePath& crash_meta_path) {
  // We send crash reports outside the VM via GRPC instead of storing them on
  // disk, so we delete files as we finish processing them.
  ScopedFileDeleter metadata_deleter(crash_meta_path);
  brillo::KeyValueStore metadata;
  if (!metadata.Load(crash_meta_path)) {
    LOG(ERROR) << "Failed to read metadata file";
    return;
  }

  grpc::ClientContext ctx;
  vm_tools::cicerone::CrashReport crash_report;
  vm_tools::EmptyMessage response;
  for (const auto& key : metadata.GetKeys()) {
    // These keys store file names, not raw values, which need to be read into
    // the crash report protobuf and deleted.
    if (base::StartsWith(key, constants::kUploadFilePrefix,
                         base::CompareCase::SENSITIVE) ||
        base::StartsWith(key, constants::kUploadTextPrefix,
                         base::CompareCase::SENSITIVE) ||
        key == "payload") {
      ProcessFileData(crash_meta_path, metadata, key, &crash_report);
    } else {
      std::string value;
      metadata.GetString(key, &value);
      (*crash_report.mutable_metadata())[key] = value;
    }
  }

  grpc::Status status = stub_->SendCrashReport(&ctx, crash_report, &response);
  if (!status.ok()) {
    LOG(ERROR) << "Failed to send crash report to cicerone: "
               << status.error_code() << ", " << status.error_message();
  }
}

bool VmSupportProper::GetMetricsConsent() {
  grpc::ClientContext ctx;
  vm_tools::EmptyMessage request;
  vm_tools::cicerone::MetricsConsentResponse response;
  grpc::Status status = stub_->CheckMetricsConsent(&ctx, request, &response);
  return status.ok() && response.consent_granted();
}

bool VmSupportProper::ShouldDump(pid_t pid, std::string* out_reason) {
  // Namespaces are accessed via the /proc/*/ns/* set of paths. The kernel
  // guarantees that if two processes share a namespace, their corresponding
  // namespace files will have the same inode number, as reported by stat.
  //
  // For now, we are only interested in processes in the root PID
  // namespace. When invoked by the kernel in response to a crash,
  // crash_reporter will be run in the root of all the namespace hierarchies, so
  // we can easily check this by comparing the crashed process PID namespace
  // with our own.
  struct stat st;

  auto namespace_path = base::StringPrintf("/proc/%d/ns/pid", pid);
  if (stat(namespace_path.c_str(), &st) < 0) {
    *out_reason = "failed to get process PID namespace";
    return false;
  }
  ino_t inode = st.st_ino;

  if (stat("/proc/self/ns/pid", &st) < 0) {
    *out_reason = "failed to get own PID namespace";
    return false;
  }
  ino_t self_inode = st.st_ino;

  if (inode != self_inode) {
    *out_reason = "ignoring - process not in root namespace";
    return false;
  }

  return true;
}
