// Copyright 2015 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/arc_collector.h"

#include <sysexits.h>
#include <unistd.h>

#include <ctime>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include <base/files/file.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringize_macros.h>
#include <base/time/time.h>
#include <brillo/key_value_store.h>
#include <brillo/process/process.h>

#include "crash-reporter/arc_util.h"
#include "crash-reporter/util.h"

using base::File;
using base::FilePath;
using base::ReadFileToString;

using brillo::ProcessImpl;

namespace {

const FilePath kContainersDir("/run/containers");
const char kArcDirPattern[] = "android*";
const FilePath kContainerPid("container.pid");

const char kArcBuildProp[] = "/run/arc/host_generated/build.prop";

const char kCoreCollectorPath[] = "/usr/bin/core_collector";
const char kCoreCollector32Path[] = "/usr/bin/core_collector32";
const char kCoreCollector64Path[] = "/usr/bin/core_collector64";

// Keys for build properties.
const char kBoardProperty[] = "ro.product.board";
const char kCpuAbiProperty[] = "ro.product.cpu.abi";
const char kDeviceProperty[] = "ro.product.device";
const char kFingerprintProperty[] = "ro.build.fingerprint";
const char kAbiMigrationStateProperty[] = "arc.abi.migrationstatus";

const size_t kBufferSize = 4096;

inline bool IsAppProcess(const std::string& name) {
  return name == "app_process32" || name == "app_process64";
}

bool ReadCrashLogFromStdin(std::stringstream* stream);

bool GetArcRoot(FilePath* root);
bool GetArcProperties(arc_util::BuildProperty* build_property);
// Get ARC primary ABI 32 bits to 64 bits migration status from ARC container.
// This is for container only. ARCVM should have separate implementation.
// See b/170238737 for detail.
bool GetAbiMigrationState(std::string* state);

}  // namespace

ArcCollector::ArcCollector() : ArcCollector(ContextPtr(new ArcContext(this))) {}

ArcCollector::ArcCollector(ContextPtr context)
    : UserCollectorBase("ARC", kAlwaysUseUserCrashDirectory),
      context_(std::move(context)) {}

bool ArcCollector::IsArcProcess(pid_t pid) const {
  pid_t arc_pid;
  if (!context_->GetArcPid(&arc_pid)) {
    LOG(ERROR) << "Failed to get PID of ARC container";
    return false;
  }
  std::string arc_ns;
  if (!context_->GetPidNamespace(arc_pid, &arc_ns)) {
    LOG(ERROR) << "Failed to get PID namespace of ARC container";
    return false;
  }
  std::string ns;
  if (!context_->GetPidNamespace(pid, &ns)) {
    LOG(ERROR) << "Failed to get PID namespace of process";
    return false;
  }
  return ns == arc_ns;
}

bool ArcCollector::HandleJavaCrash(
    const std::string& crash_type,
    const arc_util::BuildProperty& build_property,
    base::TimeDelta uptime) {
  std::string reason;
  const bool should_dump = UserCollectorBase::ShouldDump(&reason);

  std::ostringstream message;
  message << "Received " << crash_type << " notification";

  if (!should_dump) {
    LogCrash(message.str(), reason);
    close(STDIN_FILENO);
    return true;
  }

  std::stringstream stream;
  if (!ReadCrashLogFromStdin(&stream)) {
    PLOG(ERROR) << "Failed to read crash log";
    return false;
  }

  CrashLogHeaderMap map;
  std::string exception_info, log;
  if (!arc_util::ParseCrashLog(crash_type, &stream, &map, &exception_info,
                               &log)) {
    LOG(ERROR) << "Failed to parse crash log";
    return false;
  }

  const auto exec = arc_util::GetCrashLogHeader(map, arc_util::kProcessKey);
  message << " for " << exec;
  LogCrash(message.str(), reason);

  bool out_of_capacity = false;
  if (!CreateReportForJavaCrash(crash_type, build_property, map, exception_info,
                                log, uptime, &out_of_capacity)) {
    if (!out_of_capacity) {
      EnqueueCollectionErrorLog(kErrorSystemIssue, exec);
    }
    return false;
  }

  return true;
}

// static
bool ArcCollector::IsArcRunning() {
  return GetArcPid(nullptr);
}

// static
bool ArcCollector::GetArcPid(pid_t* arc_pid) {
  base::FileEnumerator containers(
      kContainersDir, false, base::FileEnumerator::DIRECTORIES, kArcDirPattern);

  for (FilePath container = containers.Next(); !container.empty();
       container = containers.Next()) {
    std::string contents;
    if (!ReadFileToString(container.Append(kContainerPid), &contents) ||
        contents.empty())
      continue;

    contents.pop_back();  // Trim EOL.

    pid_t pid;
    if (!base::StringToInt(contents, &pid) ||
        !base::PathExists(GetProcessPath(pid)))
      continue;

    if (arc_pid)
      *arc_pid = pid;

    return true;
  }

  return false;
}

bool ArcCollector::ArcContext::GetArcPid(pid_t* pid) const {
  return ArcCollector::GetArcPid(pid);
}

bool ArcCollector::ArcContext::GetPidNamespace(pid_t pid,
                                               std::string* ns) const {
  const FilePath path = GetProcessPath(pid).Append("ns").Append("pid");

  // The /proc/[pid]/ns/pid file is a special symlink that resolves to a string
  // containing the inode number of the PID namespace, e.g. "pid:[4026531838]".
  FilePath target;
  if (!base::ReadSymbolicLink(path, &target)) {
    PLOG(ERROR) << "Failed reading symbolic link: " << path.value();
    return false;
  }

  *ns = target.value();
  return true;
}

bool ArcCollector::ArcContext::GetExeBaseName(pid_t pid,
                                              std::string* exe) const {
  return collector_->CrashCollector::GetExecutableBaseNameFromPid(pid, exe);
}

bool ArcCollector::ArcContext::GetCommand(pid_t pid,
                                          std::string* command) const {
  std::vector<std::string> args = collector_->GetCommandLine(pid);
  if (args.size() == 0)
    return false;
  // Return the command and discard the arguments.
  *command = args[0];
  return true;
}

bool ArcCollector::ArcContext::ReadAuxvForProcess(pid_t pid,
                                                  std::string* contents) const {
  // The architecture with the largest auxv size is powerpc with 400 bytes.
  // Round it up to the next power of two.
  constexpr size_t kMaxAuxvSize = 512;
  const FilePath auxv_path = GetProcessPath(pid).Append("auxv");
  return base::ReadFileToStringWithMaxSize(auxv_path, contents, kMaxAuxvSize);
}

std::string ArcCollector::GetProductVersion() const {
  std::string version;
  return arc_util::GetChromeVersion(&version) ? version : kUnknownValue;
}

bool ArcCollector::GetExecutableBaseNameFromPid(pid_t pid,
                                                std::string* base_name) {
  if (!context_->GetExeBaseName(pid, base_name))
    return false;

  // The runtime for non-native ARC apps overwrites its command line with the
  // package name of the app, so use that instead.
  if (IsArcProcess(pid) && IsAppProcess(*base_name)) {
    if (!context_->GetCommand(pid, base_name))
      LOG(ERROR) << "Failed to get package name";
  }
  return true;
}

bool ArcCollector::ShouldDump(pid_t pid,
                              uid_t uid,
                              const std::string& exec,
                              std::string* reason) {
  if (!IsArcProcess(pid)) {
    *reason = "ignoring - crash origin is not ARC";
    return false;
  }

  if (uid >= kSystemUserEnd) {
    *reason = "ignoring - not a system process";
    return false;
  }

  return UserCollectorBase::ShouldDump(reason);
}

UserCollectorBase::ErrorType ArcCollector::ConvertCoreToMinidump(
    pid_t pid,
    const base::FilePath& container_dir,
    const base::FilePath& core_path,
    const base::FilePath& minidump_path) {
  FilePath root;
  if (!GetArcRoot(&root)) {
    LOG(ERROR) << "Failed to get ARC root";
    return kErrorSystemIssue;
  }

  const char* collector_path = kCoreCollectorPath;
  bool is_64_bit;
  ErrorType elf_class_error = Is64BitProcess(pid, &is_64_bit);
  // Still try to run core_collector32 if 64-bit detection failed.
  if (__WORDSIZE == 64 && (elf_class_error != kErrorNone || !is_64_bit))
    collector_path = kCoreCollector32Path;

  // Still try to run core_collector64 if 64-bit detection failed.
  if (__WORDSIZE == 32 && (elf_class_error != kErrorNone || is_64_bit))
    collector_path = kCoreCollector64Path;

  ProcessImpl core_collector;
  core_collector.AddArg(collector_path);
  core_collector.AddArg("--minidump");
  core_collector.AddArg(minidump_path.value());
  core_collector.AddArg("--coredump");
  core_collector.AddArg(core_path.value());
  core_collector.AddArg("--proc");
  core_collector.AddArg(container_dir.value());
  core_collector.AddArg("--prefix");
  core_collector.AddArg(root.value());

  std::string error;
  int exit_code =
      util::RunAndCaptureOutput(&core_collector, STDERR_FILENO, &error);

  if (exit_code < 0) {
    PLOG(ERROR) << "Failed to start " << collector_path;
    return kErrorSystemIssue;
  }

  if (exit_code == EX_OK) {
    std::string process;
    ArcCollector::GetExecutableBaseNameFromPid(pid, &process);
    AddArcMetaData(process, "native_crash", true, base::TimeDelta());
    return kErrorNone;
  }

  util::LogMultilineError(error);

  LOG(ERROR) << collector_path << " failed with exit code " << exit_code;
  switch (exit_code) {
    case EX_OSFILE:
      return kErrorInvalidCoreFile;
    case EX_SOFTWARE:
      return kErrorCore2MinidumpConversion;
    default:
      return base::PathExists(core_path) ? kErrorSystemIssue
                                         : kErrorReadCoreData;
  }
}

void ArcCollector::AddArcMetaData(const std::string& process,
                                  const std::string& crash_type,
                                  bool add_arc_properties,
                                  base::TimeDelta uptime) {
  AddCrashMetaUploadData(arc_util::kProductField, arc_util::kArcProduct);
  AddCrashMetaUploadData(arc_util::kProcessField, process);
  AddCrashMetaUploadData(arc_util::kCrashTypeField, crash_type);
  AddCrashMetaUploadData(arc_util::kChromeOsVersionField, GetOsVersion());

  arc_util::BuildProperty build_property;

  if (add_arc_properties) {
    if (GetArcProperties(&build_property)) {
      for (auto metadata :
           arc_util::ListMetadataForBuildProperty(build_property)) {
        AddCrashMetaUploadData(metadata.first, metadata.second);
      }
    }
    std::string abi_migration_state;
    // Error logging sits inside |GetAbiMigrationState|
    if (GetAbiMigrationState(&abi_migration_state))
      AddCrashMetaUploadData(arc_util::kAbiMigrationField, abi_migration_state);
  }

#if USE_ARCPP
  if (uptime.is_zero()) {
    SetUpDBus();
    if (!arc_util::GetArcContainerUptime(session_manager_proxy_.get(),
                                         &uptime)) {
      uptime = base::TimeDelta();
    }
  }
#endif  // USE_ARCPP
  if (!uptime.is_zero()) {
    AddCrashMetaUploadData(arc_util::kUptimeField,
                           arc_util::FormatDuration(uptime));
  }

  if (arc_util::IsSilentReport(crash_type))
    AddCrashMetaData(arc_util::kSilentKey, "true");
}

bool ArcCollector::CreateReportForJavaCrash(
    const std::string& crash_type,
    const arc_util::BuildProperty& build_property,
    const CrashLogHeaderMap& map,
    const std::string& exception_info,
    const std::string& log,
    base::TimeDelta uptime,
    bool* out_of_capacity) {
  FilePath crash_dir;
  if (!GetCreatedCrashDirectoryByEuid(geteuid(), &crash_dir, out_of_capacity)) {
    LOG(ERROR) << "Failed to create or find crash directory";
    return false;
  }

  const auto process = arc_util::GetCrashLogHeader(map, arc_util::kProcessKey);
  pid_t dt = arc_util::CreateRandomPID();
  const auto basename = FormatDumpBasename(process, std::time(nullptr), dt);
  const FilePath log_path = GetCrashPath(crash_dir, basename, "log");

  const int size = static_cast<int>(log.size());
  if (WriteNewFile(log_path, log.c_str(), size) != size) {
    PLOG(ERROR) << "Failed to write log";
    return false;
  }

  AddArcMetaData(process, crash_type, false, uptime);
  AddCrashMetaUploadData(arc_util::kArcVersionField,
                         build_property.fingerprint);
  AddCrashMetaUploadData(
      arc_util::kAndroidVersionField,
      arc_util::GetVersionFromFingerprint(build_property.fingerprint)
          .value_or(kUnknownValue));
  AddCrashMetaUploadData(arc_util::kDeviceField, build_property.device);
  AddCrashMetaUploadData(arc_util::kBoardField, build_property.board);
  AddCrashMetaUploadData(arc_util::kCpuAbiField, build_property.cpu_abi);

  for (const auto& mapping : arc_util::kHeaderToFieldMapping) {
    if (map.count(mapping.first)) {
      AddCrashMetaUploadData(mapping.second,
                             arc_util::GetCrashLogHeader(map, mapping.first));
    }
  }

  if (exception_info.empty()) {
    if (const char* const tag = arc_util::GetSubjectTag(crash_type)) {
      std::ostringstream out;
      out << '[' << tag << ']';
      const auto it = map.find(arc_util::kSubjectKey);
      if (it != map.end())
        out << ' ' << it->second;

      AddCrashMetaData(arc_util::kSignatureField, out.str());
    } else {
      LOG(ERROR) << "Invalid crash type: " << crash_type;
      return false;
    }
  } else {
    const FilePath info_path = GetCrashPath(crash_dir, basename, "info");
    const int size = static_cast<int>(exception_info.size());

    if (WriteNewFile(info_path, exception_info.c_str(), size) != size) {
      PLOG(ERROR) << "Failed to write exception info";
      return false;
    }

    AddCrashMetaUploadText(arc_util::kExceptionInfoField,
                           info_path.BaseName().value());
  }

  const FilePath meta_path = GetCrashPath(crash_dir, basename, "meta");
  FinishCrash(meta_path, process, log_path.BaseName().value());
  return true;
}

UserCollectorBase::ErrorType ArcCollector::Is64BitProcess(
    int pid, bool* is_64_bit) const {
  std::string auxv_contents;
  if (!context_->ReadAuxvForProcess(pid, &auxv_contents)) {
    PLOG(ERROR) << "Could not read /proc/" << pid << "/auxv";
    return kErrorSystemIssue;
  }
  // auxv is an array of unsigned long[2], and the first element in each entry
  // is an AT_* key. We assume we are running a 32-bit process (hence the
  // |*is_64_bit| below), and then try to see if any of the keys seem off.
  // All AT_* keys are less than ~48, so if we find any key that exceeds 256, we
  // definitely know it is not a 32-bit process. This will almost always trigger
  // correctly because some of the values in the auxv are pointers and their
  // high bits are almost always non-zero. For illustration purposes, consider
  // the following auxv taken from a x86_64 machine:
  //
  // |-------64-bit key------|-----64-bit value------|
  // |32-bit key-|32-bit val-|32-bit key-|32-bit val-|
  //  21 00 00 00 00 00 00 00 00 30 db e6 fe 7f 00 00
  //  10 00 00 00 00 00 00 00 ff fb eb bf 00 00 00 00
  //  06 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00
  //  ...
  //
  //  When interpreted as 64-bit unsigned longs, all the keys are less than 256,
  //  but when interpreted as 32-bit unsigned longs, some of the "keys" will
  //  contain the upper parts of addresses.
  struct Auxv32BitEntry {
    uint32_t key;
    uint32_t value;
  };
  if (auxv_contents.size() % sizeof(Auxv32BitEntry) != 0) {
    LOG(ERROR) << "Could not parse the contents of the auxv file. "
               << "Size not a multiple of 8: " << auxv_contents.size();
    return kErrorSystemIssue;
  }
  *is_64_bit = false;

  const Auxv32BitEntry* auxv_32_bit_entries =
      reinterpret_cast<const Auxv32BitEntry*>(auxv_contents.data());
  const size_t auxv_32_bit_entries_length =
      auxv_contents.size() / sizeof(Auxv32BitEntry);

  for (size_t i = 0; i < auxv_32_bit_entries_length; ++i) {
    if (auxv_32_bit_entries[i].key > 256) {
      *is_64_bit = true;
      break;
    }
  }

  return kErrorNone;
}

namespace {

bool ReadCrashLogFromStdin(std::stringstream* stream) {
  File src(STDIN_FILENO);
  char buffer[kBufferSize];

  while (true) {
    const int count = src.ReadAtCurrentPosNoBestEffort(buffer, kBufferSize);
    if (count < 0)
      return false;

    if (count == 0)
      return stream->tellp() > 0;  // Crash log should not be empty.

    stream->write(buffer, count);
  }
}

bool GetArcRoot(FilePath* root) {
  base::FileEnumerator containers(
      kContainersDir, false, base::FileEnumerator::DIRECTORIES, kArcDirPattern);

  for (FilePath container = containers.Next(); !container.empty();
       container = containers.Next()) {
    const FilePath path = container.Append("root");
    if (base::PathExists(path)) {
      *root = path;
      return true;
    }
  }

  return false;
}

bool GetArcProperties(arc_util::BuildProperty* build_property) {
  FilePath root;
  brillo::KeyValueStore store;
  if (store.Load(FilePath(kArcBuildProp)) &&
      store.GetString(kFingerprintProperty, &(build_property->fingerprint)) &&
      store.GetString(kDeviceProperty, &(build_property->device)) &&
      store.GetString(kBoardProperty, &(build_property->board)) &&
      store.GetString(kCpuAbiProperty, &(build_property->cpu_abi)))
    return true;

  LOG(ERROR) << "Failed to get ARC properties";
  return false;
}

bool GetAbiMigrationState(std::string* state) {
  brillo::ProcessImpl androidsh;
  androidsh.AddArg("/usr/sbin/android-sh");
  androidsh.AddArg("-c");
  androidsh.AddArg(std::string("getprop ") + kAbiMigrationStateProperty);

  base::FilePath temp_file;
  if (!base::CreateTemporaryFile(&temp_file)) {
    LOG(ERROR) << "Fail to create tmp file to receive result from getprop cmd.";
    return false;
  }
  androidsh.RedirectOutput(temp_file.value());
  int result = androidsh.Run();
  if (result == 0) {
    if (!base::ReadFileToString(temp_file, state)) {
      LOG(ERROR) << "Fail to read result of getprop cmd from tmp file";
      return false;
    }
    base::TrimWhitespaceASCII(*state, base::TRIM_TRAILING, state);
    return !state->empty();
  } else {
    LOG(ERROR) << "Process for android-sh fail to run, err code: " << result;
    return false;
  }
}

}  // namespace
