// Copyright 2018 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 <stdlib.h>
#include <sys/capability.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <limits>
#include <memory>

#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/time/default_clock.h>
#include <brillo/syslog_logging.h>
#include <libminijail.h>
#include <metrics/metrics_library.h>
#include <scoped_minijail.h>

#include "crash-reporter/crash_sender_paths.h"
#include "crash-reporter/crash_sender_util.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/util.h"

namespace {
// Sets up the minijail sandbox.
//
// crash_sender currently needs to run as root:
// - System crash reports in /var/spool/crash are owned by root.
// - User crash reports in /home/chronos/ are owned by chronos.
//
// crash_sender needs network access in order to upload things.
//
void SetUpSandbox(struct minijail* jail) {
  // Keep CAP_DAC_OVERRIDE in order to access non-root paths.
  minijail_use_caps(jail, CAP_TO_MASK(CAP_DAC_OVERRIDE));
  // Set ambient capabilities because crash_sender runs other programs.
  // TODO(satorux): Remove this once the code is entirely C++.
  minijail_set_ambient_caps(jail);
  minijail_no_new_privs(jail);
  minijail_namespace_ipc(jail);
  minijail_namespace_pids(jail);
  minijail_remount_proc_readonly(jail);
  minijail_namespace_vfs(jail);
  minijail_mount_tmp(jail);
  minijail_namespace_uts(jail);
  minijail_forward_signals(jail);
}

// Runs the main function for the child process.
int RunChildMain(int argc, char* argv[]) {
  util::CommandLineFlags flags;
  util::ParseCommandLine(argc, argv, &flags);

  if (util::DoesPauseFileExist() && !flags.ignore_pause_file) {
    LOG(INFO) << "Exiting early due to " << paths::kPauseCrashSending;
    return EXIT_FAILURE;
  }

  auto clock = std::make_unique<base::DefaultClock>();

  if (flags.test_mode) {
    LOG(INFO) << "--test_mode present; will not actually upload to server.";
  } else if (flags.allow_dev_sending) {
    LOG(INFO) << "--dev flag present, ignore image checks and uploading "
              << "crashes to staging server at go/crash-staging";
  } else {
    // Normal mode (not test, not dev).
    if (util::IsTestImage()) {
      LOG(INFO) << "Exiting early due to test image.";
      return EXIT_FAILURE;
    }

    if (util::IsOsTimestampTooOldForUploads(util::GetOsTimestamp(),
                                            clock.get())) {
      LOG(INFO) << "Version is too old, will not upload crash reports";
      return EXIT_FAILURE;
    }
  }

  auto metrics_lib = std::make_unique<MetricsLibrary>();
  util::Sender::Options options;
  options.max_spread_time = flags.max_spread_time;
  if (flags.ignore_rate_limits) {
    options.max_crash_rate = std::numeric_limits<int>::max();
    options.max_crash_bytes = std::numeric_limits<int>::max();
  }
  if (flags.ignore_hold_off_time) {
    options.hold_off_time = base::TimeDelta::FromSeconds(0);
  }
  options.allow_dev_sending = flags.allow_dev_sending;
  options.test_mode = flags.test_mode;
  util::Sender sender(std::move(metrics_lib), std::move(clock), options);
  if (!sender.Init()) {
    LOG(ERROR) << "Failed to initialize util::Sender";
    return EXIT_FAILURE;
  }

  // If you add sigificant code past this point, consider updating
  // crash_sender_fuzzer.cc as well.

  // Get all reports we might want to send, and then choose the more important
  // report out of all the directories to send first.
  std::vector<base::FilePath> crash_directories;
  if (flags.crash_directory.empty()) {
    crash_directories = sender.GetUserCrashDirectories();
    crash_directories.push_back(paths::Get(paths::kSystemCrashDirectory));
    crash_directories.push_back(paths::Get(paths::kFallbackUserCrashDirectory));
  } else {
    crash_directories.push_back(base::FilePath(flags.crash_directory));
  }

  // Add the stateful partition's crash directory: the crashes and logs stored
  // here usually are indicative of the state of the machine during the last
  // clobber.
  crash_directories.push_back(
      paths::Get(paths::kStatefulClobberCrashDirectory));

  std::vector<util::MetaFile> reports_to_send;

  base::File lock_file(sender.AcquireLockFileOrDie());
  for (const auto& directory : crash_directories) {
    util::RemoveOrphanedCrashFiles(directory);
    sender.RemoveAndPickCrashFiles(directory, &reports_to_send);
  }
  lock_file.Close();

  util::SortReports(&reports_to_send);
  sender.SendCrashes(reports_to_send);

  return EXIT_SUCCESS;
}

// Cleans up. This function runs in the parent process (not sandboxed), hence
// should be very minimal. No need to delete temporary files manually in /tmp,
// that's a unique tmpfs provided by minijail, that'll automatically go away
// when the child process is terminated.
void CleanUp() {
  util::RecordCrashDone();
}

}  // namespace

int main(int argc, char* argv[]) {
  // Log to syslog (/var/log/messages), and stderr if stdin is a tty.
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);
  // Register the cleanup function to be called at exit.
  atexit(&CleanUp);

  // Set up a sandbox, and jail the child process.
  ScopedMinijail jail(minijail_new());
  SetUpSandbox(jail.get());
  const pid_t pid = minijail_fork(jail.get());

  if (pid == 0)
    return RunChildMain(argc, argv);

  // We rely on the child handling its own exit status, and a non-zero status
  // isn't necessarily a bug (e.g. if mocked out that way).  Only warn for an
  // internal error.
  const int status = minijail_wait(jail.get());
  LOG_IF(ERROR, status < 0)
      << "Child process " << pid << " did not finish cleanly: " << status;
  return status;
}
