// Copyright (c) 2012 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 <fcntl.h>  // for open

#include <string>
#include <utility>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/message_loop/message_loop.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include <libminijail.h>
#include <metrics/metrics_library.h>

#include "crash-reporter/arc_collector.h"
#include "crash-reporter/arc_service_failure_collector.h"
#include "crash-reporter/bert_collector.h"
#include "crash-reporter/chrome_collector.h"
#include "crash-reporter/crash_reporter_failure_collector.h"
#include "crash-reporter/early_crash_meta_collector.h"
#include "crash-reporter/ec_collector.h"
#include "crash-reporter/generic_failure_collector.h"
#include "crash-reporter/kernel_collector.h"
#include "crash-reporter/kernel_warning_collector.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/selinux_violation_collector.h"
#include "crash-reporter/service_failure_collector.h"
#include "crash-reporter/udev_collector.h"
#include "crash-reporter/unclean_shutdown_collector.h"
#include "crash-reporter/user_collector.h"
#include "crash-reporter/util.h"

using base::FilePath;

namespace {

const char kKernelCrashDetected[] =
    "/run/metrics/external/crash-reporter/kernel-crash-detected";
const char kUncleanShutdownDetected[] =
    "/run/metrics/external/crash-reporter/unclean-shutdown-detected";
const char kBootCollectorDone[] = "/run/crash_reporter/boot-collector-done";

bool always_allow_feedback = false;

MetricsLibrary s_metrics_lib;

bool IsFeedbackAllowed() {
  if (always_allow_feedback)
    return true;
  return s_metrics_lib.AreMetricsEnabled();
}

bool TouchFile(const FilePath& file_path) {
  return base::WriteFile(file_path, "", 0) == 0;
}

int Initialize(UserCollector* user_collector,
               UdevCollector* udev_collector,
               bool early) {
  // Try to create the lock file for crash_sender. Creating this early ensures
  // that no one else can make a directory or such with this name. If the lock
  // file isn't a normal file, crash_sender will never work correctly.
  TouchFile(paths::Get(paths::kCrashSenderLockFile));

  // Set up all the common crash state directories first.  If we can't guarantee
  // these basic paths, just give up & don't turn on anything else.
  if (!CrashCollector::InitializeSystemCrashDirectories(early))
    return 1;

  // Set up metrics flag directory. Returns with non-zero if we cannot create
  // it.
  if (!CrashCollector::InitializeSystemMetricsDirectories())
    return 1;

  int ret = 0;

  if (!user_collector->Enable(early))
    ret = 1;
  if (!udev_collector->Enable())
    ret = 1;
  return ret;
}

int BootCollect(KernelCollector* kernel_collector,
                ECCollector* ec_collector,
                BERTCollector* bert_collector,
                UncleanShutdownCollector* unclean_shutdown_collector,
                EarlyCrashMetaCollector* early_crash_meta_collector) {
  bool was_kernel_crash = false;
  bool was_unclean_shutdown = false;

  /* TODO(drinkcat): Distinguish between EC crash and unclean shutdown. */
  ec_collector->Collect();

  // Invoke to collect firmware bert dump.
  bert_collector->Collect();

  kernel_collector->Enable();
  if (kernel_collector->is_enabled()) {
    was_kernel_crash = kernel_collector->Collect();
  }
  was_unclean_shutdown = unclean_shutdown_collector->Collect();

  // Touch a file to notify the metrics daemon that a kernel
  // crash has been detected so that it can log the time since
  // the last kernel crash.
  if (IsFeedbackAllowed()) {
    if (was_kernel_crash) {
      TouchFile(FilePath(kKernelCrashDetected));
    } else if (was_unclean_shutdown) {
      // We only count an unclean shutdown if it did not come with
      // an associated kernel crash.
      TouchFile(FilePath(kUncleanShutdownDetected));
    }
  }

  // Must enable the unclean shutdown collector *after* collecting.
  unclean_shutdown_collector->Enable();

  // Copy lsb-release and os-release into system crash spool.  Done after
  // collecting so that boot-time collected crashes will be associated with the
  // previous boot.
  unclean_shutdown_collector->SaveVersionData();

  // Collect early boot crashes.
  early_crash_meta_collector->Collect();

  // Presence of this files unblocks powerd from performing lid-closed action
  // (crbug.com/988831).
  TouchFile(FilePath(kBootCollectorDone));

  return 0;
}

int HandleUserCrash(UserCollector* user_collector,
                    const std::string& user,
                    const bool crash_test,
                    const bool early) {
  // Handle a specific user space crash.
  CHECK(!user.empty()) << "--user= must be set";

  // Make it possible to test what happens when we crash while
  // handling a crash.
  if (crash_test) {
    *(volatile char*)0 = 0;
    return 0;
  }

  // Accumulate logs to help in diagnosing failures during user collection.
  brillo::LogToString(true);
  // Handle the crash, get the name of the process from procfs.
  bool handled = user_collector->HandleCrash(user, nullptr);
  brillo::LogToString(false);
  if (!handled)
    return 1;
  return 0;
}

#if USE_CHEETS
int HandleArcCrash(ArcCollector* arc_collector, const std::string& user) {
  brillo::LogToString(true);
  bool handled = arc_collector->HandleCrash(user, nullptr);
  brillo::LogToString(false);
  if (!handled)
    return 1;
  return 0;
}

int HandleArcJavaCrash(ArcCollector* arc_collector,
                       const std::string& crash_type,
                       const ArcCollector::BuildProperty& build_property) {
  brillo::LogToString(true);
  bool handled = arc_collector->HandleJavaCrash(crash_type, build_property);
  brillo::LogToString(false);
  if (!handled)
    return 1;
  return 0;
}
#endif

int HandleChromeCrash(ChromeCollector* chrome_collector,
                      const std::string& chrome_dump_file,
                      pid_t pid,
                      uid_t uid,
                      const std::string& exe) {
  CHECK(!chrome_dump_file.empty()) << "--chrome= must be set";
  CHECK(pid != (pid_t)-1) << "--pid= must be set";
  CHECK(uid != (uid_t)-1) << "--uid= must be set";
  CHECK(!exe.empty()) << "--exe= must be set";

  brillo::LogToString(true);
  bool handled =
      chrome_collector->HandleCrash(FilePath(chrome_dump_file), pid, uid, exe);
  brillo::LogToString(false);
  if (!handled)
    return 1;
  return 0;
}

int HandleChromeCrashThroughMemfd(ChromeCollector* chrome_collector,
                                  int memfd,
                                  pid_t pid,
                                  uid_t uid,
                                  const std::string& exe,
                                  const std::string& dump_dir) {
  CHECK(memfd >= 0) << "--chrome_memfd= must be set";
  CHECK(pid >= (pid_t)0) << "--pid= must be set";
  CHECK(uid >= (uid_t)0) << "--uid= must be set";
  CHECK(!exe.empty()) << "--exe= must be set";

  brillo::LogToString(true);
  bool handled =
      chrome_collector->HandleCrashThroughMemfd(memfd, pid, uid, exe, dump_dir);
  brillo::LogToString(false);
  if (!handled)
    return 1;
  return 0;
}

int HandleUdevCrash(UdevCollector* udev_collector,
                    const std::string& udev_event) {
  // Handle a crash indicated by a udev event.
  CHECK(!udev_event.empty()) << "--udev= must be set";

  // Accumulate logs to help in diagnosing failures during user collection.
  brillo::LogToString(true);
  bool handled = udev_collector->HandleCrash(udev_event);
  brillo::LogToString(false);
  if (!handled)
    return 1;
  return 0;
}

int HandleKernelWarning(KernelWarningCollector* kernel_warning_collector,
                        KernelWarningCollector::WarningType type) {
  // Accumulate logs to help in diagnosing failures during collection.
  brillo::LogToString(true);
  bool handled = kernel_warning_collector->Collect(type);
  brillo::LogToString(false);
  if (!handled)
    return 1;
  return 0;
}

int HandleSuspendFailure(GenericFailureCollector* suspend_failure_collector) {
  // Accumulate logs to help in diagnosing failures during collection.
  brillo::LogToString(true);
  bool handled = suspend_failure_collector->Collect();
  brillo::LogToString(false);
  return handled ? 0 : 1;
}

int HandleServiceFailure(ServiceFailureCollector* service_failure_collector,
                         const std::string& service_name) {
  // Accumulate logs to help in diagnosing failures during collection.
  brillo::LogToString(true);
  service_failure_collector->SetServiceName(service_name);
  bool handled = service_failure_collector->Collect();
  brillo::LogToString(false);
  if (!handled)
    return 1;
  return 0;
}

int HandleSELinuxViolation(
    SELinuxViolationCollector* selinux_violation_collector) {
  brillo::LogToString(true);
  bool handled = selinux_violation_collector->Collect();
  brillo::LogToString(false);
  return handled ? 0 : 1;
}

void HandleCrashReporterFailure(
    CrashReporterFailureCollector* crash_reporter_failure_collector) {
  // Accumulate logs to help in diagnosing failures during collection.
  brillo::LogToString(true);
  crash_reporter_failure_collector->Collect();
  brillo::LogToString(false);
}

// Ensure stdout, stdin, and stderr are open file descriptors.  If
// they are not, any code which writes to stderr/stdout may write out
// to files opened during execution.  In particular, when
// crash_reporter is run by the kernel coredump pipe handler (via
// kthread_create/kernel_execve), it will not have file table entries
// 1 and 2 (stdout and stderr) populated.  We populate them here.
void OpenStandardFileDescriptors() {
  int new_fd = -1;
  // We open /dev/null to fill in any of the standard [0, 2] file
  // descriptors.  We leave these open for the duration of the
  // process.  This works because open returns the lowest numbered
  // invalid fd.
  do {
    new_fd = open("/dev/null", 0);
    CHECK_GE(new_fd, 0) << "Unable to open /dev/null";
  } while (new_fd >= 0 && new_fd <= 2);
  close(new_fd);
}

// Reduce privs that we don't need.  But we still need:
// - The top most /proc to pull details out of it.
// - Read access to the crashing process's memory (regardless of user).
// - Write access to the crash spool dir.
void EnterSandbox(bool write_proc, bool log_to_stderr) {
  // If we're not root, we won't be able to jail ourselves (well, we could if
  // we used user namespaces, but maybe later).  Need to double check handling
  // when called by chrome to process its crashes.
  if (getuid() != 0)
    return;

  struct minijail* j = minijail_new();
  minijail_namespace_ipc(j);
  minijail_namespace_uts(j);
  minijail_namespace_net(j);
  minijail_namespace_vfs(j);
  minijail_mount_tmp(j);
  minijail_mount_dev(j);
  if (!log_to_stderr)
    minijail_bind(j, "/dev/log", "/dev/log", 0);
  minijail_no_new_privs(j);
  minijail_new_session_keyring(j);

  // If we're initializing the system, we're need to write to /proc/sys/.
  if (!write_proc) {
    minijail_remount_proc_readonly(j);
  }

  minijail_enter(j);
  minijail_destroy(j);
}

}  // namespace

int main(int argc, char* argv[]) {
  DEFINE_bool(init, false, "Initialize crash logging");
  DEFINE_bool(boot_collect, false, "Run per-boot crash collection tasks");
  DEFINE_bool(clean_shutdown, false, "Signal clean shutdown");
  DEFINE_bool(crash_test, false, "Crash test");
  DEFINE_bool(early, false,
              "Modifies crash-reporter to work during early boot");
  DEFINE_bool(preserve_across_clobber, false,
              "Persist early user crash reports across clobbers.");
  DEFINE_string(user, "", "User crash info (pid:signal:exec_name)");
  DEFINE_string(udev, "", "Udev event description (type:device:subsystem)");
  DEFINE_bool(kernel_warning, false, "Report collected kernel warning");
  DEFINE_bool(kernel_wifi_warning, false,
              "Report collected kernel wifi warning");
  DEFINE_bool(kernel_suspend_warning, false,
              "Report collected kernel suspend warning");
  DEFINE_bool(log_to_stderr, false, "Log to stderr instead of syslog.");
  DEFINE_string(arc_service_failure, "",
                "The specific ARC service name that failed");
  DEFINE_bool(suspend_failure, false, "Report collected suspend failure logs.");
  DEFINE_bool(crash_reporter_crashed, false,
              "Report crash_reporter itself crashing");
  DEFINE_string(service_failure, "", "The specific service name that failed");
  DEFINE_bool(selinux_violation, false, "Report collected SELinux violation");
  // TODO(crbug.com/1000398): Remove --chrome flag after Chrome switches from
  // breakpad to crashpad.
  // Note: --chrome is being replaced by --chrome_memfd;
  //       --chrome_dump_dir is only used for tests and only used when
  // --chrome_memfd is used and not when --chrome is used.
  DEFINE_string(chrome, "", "Chrome crash dump file");
  DEFINE_int32(chrome_memfd, -1, "Chrome crash dump memfd");
  DEFINE_string(chrome_dump_dir, "",
                "Directory to write Chrome minidumps, used for tests only");
  DEFINE_int32(pid, -1, "PID of crashing process");
  DEFINE_int32(uid, -1, "UID of crashing process");
  DEFINE_string(exe, "", "Executable name of crashing process");
  DEFINE_int64(crash_loop_before, -1,
               "UNIX timestamp. If invoked before this time, use the special "
               "login-crash-loop handling system. (Keep crash report in memory "
               "and then pass to debugd for immediate upload.)")
      DEFINE_bool(core2md_failure, false, "Core2md failure test");
  DEFINE_bool(directory_failure, false, "Spool directory failure test");
  DEFINE_string(filter_in, "", "Ignore all crashes but this for testing");
  DEFINE_bool(
      always_allow_feedback, false,
      "Force if feedback is allowed check to return true, used for tests only");
#if USE_CHEETS
  DEFINE_string(arc_java_crash, "",
                "Read Java crash log of the given type from standard input");
  DEFINE_string(arc_device, "", "Metadata for --arc_java_crash");
  DEFINE_string(arc_board, "", "Metadata for --arc_java_crash");
  DEFINE_string(arc_cpu_abi, "", "Metadata for --arc_java_crash");
#endif

  OpenStandardFileDescriptors();
  FilePath my_path = base::MakeAbsoluteFilePath(FilePath(argv[0]));
  brillo::FlagHelper::Init(argc, argv, "Chromium OS Crash Reporter");

  base::MessageLoopForIO message_loop;

  // In certain cases, /dev/log may not be available: log to stderr instead.
  if (FLAGS_log_to_stderr) {
    brillo::InitLog(brillo::kLogToStderr);
  } else {
    brillo::OpenLog(my_path.BaseName().value().c_str(), true);
    brillo::InitLog(brillo::kLogToSyslog);
  }

  if (FLAGS_always_allow_feedback) {
    CHECK(util::IsTestImage()) << "--always_allow_feedback is only for tests";
    always_allow_feedback = true;
  }

  // Now that we've processed the command line, sandbox ourselves.
  EnterSandbox(FLAGS_init || FLAGS_clean_shutdown, FLAGS_log_to_stderr);

  EarlyCrashMetaCollector early_crash_meta_collector;
  early_crash_meta_collector.Initialize(IsFeedbackAllowed,
                                        FLAGS_preserve_across_clobber);

  // Decide if we should use Crash-Loop sending mode. If session_manager sees
  // several Chrome crashes in a brief period, it will log the user out. On the
  // last Chrome startup before it logs the user out, it will set the
  // --crash_loop_before flag. The value of the flag will be a time_t timestamp
  // giving the last second at which a crash would be considered a crash loop
  // and thus log the user out. If we have another crash before that second,
  // we have detected a crash-loop and we want to invoke special handling
  // (specifically, we don't want to save the crash in the user's home directory
  // because that will be inaccessible to crash_sender once the user is logged
  // out).
  CrashCollector::CrashSendingMode crash_sending_mode =
      CrashCollector::kNormalCrashSendMode;
  if (FLAGS_crash_loop_before >= 0) {
    base::Time crash_loop_before =
        base::Time::FromTimeT(static_cast<time_t>(FLAGS_crash_loop_before));
    if (base::Time::Now() <= crash_loop_before) {
      crash_sending_mode = CrashCollector::kCrashLoopSendingMode;
    }
  }

  KernelCollector kernel_collector;
  kernel_collector.Initialize(IsFeedbackAllowed, FLAGS_early);
  ECCollector ec_collector;
  ec_collector.Initialize(IsFeedbackAllowed, FLAGS_early);
  BERTCollector bert_collector;
  bert_collector.Initialize(IsFeedbackAllowed, FLAGS_early);
  UserCollector user_collector;
  UserCollector::FilterOutFunction filter_out = [](pid_t) { return false; };
#if USE_CHEETS
  ArcCollector arc_collector;
  arc_collector.Initialize(IsFeedbackAllowed,
                           true,  // generate_diagnostics
                           FLAGS_directory_failure, FLAGS_filter_in,
                           false /* early */);
  // Filter out ARC processes.
  if (ArcCollector::IsArcRunning())
    filter_out = std::bind(&ArcCollector::IsArcProcess, &arc_collector,
                           std::placeholders::_1);
#endif
  user_collector.Initialize(my_path.value(), IsFeedbackAllowed,
                            true,  // generate_diagnostics
                            FLAGS_core2md_failure, FLAGS_directory_failure,
                            FLAGS_filter_in, std::move(filter_out),
                            FLAGS_early);
  UncleanShutdownCollector unclean_shutdown_collector;
  unclean_shutdown_collector.Initialize(IsFeedbackAllowed, FLAGS_early);

  UdevCollector udev_collector;
  udev_collector.Initialize(IsFeedbackAllowed, FLAGS_early);
  ChromeCollector chrome_collector(crash_sending_mode);
  chrome_collector.Initialize(IsFeedbackAllowed, FLAGS_early);

  KernelWarningCollector kernel_warning_collector;
  kernel_warning_collector.Initialize(IsFeedbackAllowed, FLAGS_early);

  ArcServiceFailureCollector arc_service_failure_collector;
  arc_service_failure_collector.Initialize(IsFeedbackAllowed, FLAGS_early);

  ServiceFailureCollector service_failure_collector;
  service_failure_collector.Initialize(IsFeedbackAllowed, FLAGS_early);

  GenericFailureCollector suspend_failure_collector(
      GenericFailureCollector::kSuspendFailure);
  suspend_failure_collector.Initialize(IsFeedbackAllowed, FLAGS_early);

  SELinuxViolationCollector selinux_violation_collector;
  selinux_violation_collector.Initialize(IsFeedbackAllowed, FLAGS_early);

  CrashReporterFailureCollector crash_reporter_failure_collector;
  crash_reporter_failure_collector.Initialize(IsFeedbackAllowed, FLAGS_early);

  if (FLAGS_init) {
    return Initialize(&user_collector, &udev_collector, FLAGS_early);
  }

  if (FLAGS_boot_collect) {
    return BootCollect(&kernel_collector, &ec_collector, &bert_collector,
                       &unclean_shutdown_collector,
                       &early_crash_meta_collector);
  }

  if (FLAGS_clean_shutdown) {
    int ret = 0;
    if (!unclean_shutdown_collector.Disable())
      ret = 1;
    if (!user_collector.Disable())
      ret = 1;
    return ret;
  }

  if (!FLAGS_udev.empty()) {
    return HandleUdevCrash(&udev_collector, FLAGS_udev);
  }

  if (FLAGS_kernel_warning) {
    return HandleKernelWarning(&kernel_warning_collector,
                               KernelWarningCollector::WarningType::kGeneric);
  }

  if (FLAGS_kernel_wifi_warning) {
    return HandleKernelWarning(&kernel_warning_collector,
                               KernelWarningCollector::WarningType::kWifi);
  }

  if (FLAGS_kernel_suspend_warning) {
    return HandleKernelWarning(&kernel_warning_collector,
                               KernelWarningCollector::WarningType::kSuspend);
  }

  if (!FLAGS_arc_service_failure.empty()) {
    return HandleServiceFailure(&arc_service_failure_collector,
                                FLAGS_arc_service_failure);
  }

  if (FLAGS_suspend_failure) {
    return HandleSuspendFailure(&suspend_failure_collector);
  }

  if (!FLAGS_service_failure.empty()) {
    return HandleServiceFailure(&service_failure_collector,
                                FLAGS_service_failure);
  }

  if (FLAGS_selinux_violation) {
    return HandleSELinuxViolation(&selinux_violation_collector);
  }

  if (FLAGS_crash_reporter_crashed) {
    HandleCrashReporterFailure(&crash_reporter_failure_collector);
    return 0;
  }

  if (!FLAGS_chrome.empty()) {
    CHECK(FLAGS_chrome_memfd == -1)
        << "--chrome= and --chrome_memfd= cannot be both set";
    return HandleChromeCrash(&chrome_collector, FLAGS_chrome, FLAGS_pid,
                             FLAGS_uid, FLAGS_exe);
  }

  if (FLAGS_chrome_memfd != -1) {
    CHECK(FLAGS_chrome_dump_dir.empty() || util::IsTestImage())
        << "--chrome_dump_dir is only for tests";
    return HandleChromeCrashThroughMemfd(&chrome_collector, FLAGS_chrome_memfd,
                                         FLAGS_pid, FLAGS_uid, FLAGS_exe,
                                         FLAGS_chrome_dump_dir);
  }

#if USE_CHEETS
  if (!FLAGS_arc_java_crash.empty()) {
    ArcCollector::BuildProperty build_property = {.device = FLAGS_arc_device,
                                                  .board = FLAGS_arc_board,
                                                  .cpu_abi = FLAGS_arc_cpu_abi};
    return HandleArcJavaCrash(&arc_collector, FLAGS_arc_java_crash,
                              build_property);
  }
#endif

  int exit_code = HandleUserCrash(&user_collector, FLAGS_user, FLAGS_crash_test,
                                  FLAGS_early);
#if USE_CHEETS
  if (ArcCollector::IsArcRunning())
    exit_code |= HandleArcCrash(&arc_collector, FLAGS_user);
#endif
  return exit_code;
}
