// 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 "crash-reporter/util.h"

#include <poll.h>
#include <signal.h>
#include <stdlib.h>

#include <algorithm>
#include <map>
#include <memory>

#include <base/check_op.h>
#include <base/logging.h>

#if USE_DIRENCRYPTION
#include <keyutils.h>
#endif  // USE_DIRENCRYPTION

#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <brillo/cryptohome.h>
#include <brillo/key_value_store.h>
#include <brillo/userdb_utils.h>
#include <zlib.h>

#include "crash-reporter/crossystem.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/vm_support.h"

namespace util {

namespace {

constexpr size_t kBufferSize = 4096;

// Path to hardware class description.
constexpr char kHwClassPath[] = "/sys/devices/platform/chromeos_acpi/HWID";

constexpr char kDevSwBoot[] = "devsw_boot";
constexpr char kDevMode[] = "dev";

// If the OS version is older than this we do not upload crash reports.
constexpr base::TimeDelta kAgeForNoUploads = base::TimeDelta::FromDays(180);

#if USE_DIRENCRYPTION
// Name of the session keyring.
const char kDircrypt[] = "dircrypt";
#endif  // USE_DIRENCRYPTION

}  // namespace

const int kDefaultMaxUploadBytes = 1024 * 1024;

bool IsCrashTestInProgress() {
  return base::PathExists(paths::GetAt(paths::kSystemRunStateDirectory,
                                       paths::kCrashTestInProgress));
}

bool IsDeviceCoredumpUploadAllowed() {
  return base::PathExists(paths::GetAt(paths::kCrashReporterStateDirectory,
                                       paths::kDeviceCoredumpUploadAllowed));
}

bool IsDeveloperImage() {
  // If we're testing crash reporter itself, we don't want to special-case
  // for developer images.
  if (IsCrashTestInProgress())
    return false;
  return base::PathExists(paths::Get(paths::kLeaveCoreFile));
}

// Determines if this is a test image, IGNORING IsCrashTestInProgress.
// Use sparingly, and only if you're really sure you want to have different
// behavior during crash tests than on real devices.
bool IsReallyTestImage() {
  std::string channel;
  if (!GetCachedKeyValueDefault(base::FilePath(paths::kLsbRelease),
                                "CHROMEOS_RELEASE_TRACK", &channel)) {
    return false;
  }
  return base::StartsWith(channel, "test", base::CompareCase::SENSITIVE);
}

bool IsTestImage() {
  // If we're testing crash reporter itself, we don't want to special-case
  // for test images.
  if (IsCrashTestInProgress())
    return false;

  return IsReallyTestImage();
}

bool IsOfficialImage() {
  std::string description;
  if (!GetCachedKeyValueDefault(base::FilePath(paths::kLsbRelease),
                                "CHROMEOS_RELEASE_DESCRIPTION", &description)) {
    return false;
  }

  return description.find("Official") != std::string::npos;
}

bool HasMockConsent() {
  // Don't bypass user consent on real Chromebooks; this is for testing.
  // We can't use IsTestImage because that's always false if a crash test is in
  // progress.
  if (!IsReallyTestImage()) {
    return false;
  }
  return base::PathExists(
      paths::GetAt(paths::kSystemRunStateDirectory, paths::kMockConsent));
}

bool IsFeedbackAllowed(MetricsLibraryInterface* metrics_lib) {
  if (HasMockConsent()) {
    LOG(INFO) << "mock-consent file present; assuming consent";
    return true;
  }
  // For developer builds, we always want to keep the crash reports unless
  // we're testing the crash facilities themselves.  This overrides
  // feedback.  Crash sending still obeys consent.
  if (IsDeveloperImage()) {
    LOG(INFO) << "developer build - not testing - always dumping";
    return true;
  }

  VmSupport* vm_support = VmSupport::Get();
  bool ret = false;
  if (vm_support) {
    ret = vm_support->GetMetricsConsent();
  } else {
    ret = metrics_lib->AreMetricsEnabled();
  }

  if (!ret) {
    LOG(WARNING)
        << "No consent. Not handling invocation: "
        << base::CommandLine::ForCurrentProcess()->GetCommandLineString();
  }

  return ret;
}

// Determine if the filter-in file tells us to skip
static bool SkipForFilterIn(std::string command_line) {
  base::FilePath file =
      paths::GetAt(paths::kSystemRunStateDirectory, paths::kFilterInFile);
  if (!base::PathExists(file)) {
    return false;
  }

  std::string contents;
  if (!base::ReadFileToString(file, &contents)) {
    LOG(WARNING) << "Failed to read " << file;
    return false;
  }

  if (contents == "none" || command_line.find(contents) == std::string::npos) {
    // Doesn't match, so skip this crash.
    LOG(WARNING) << "Ignoring crash invocation '" << command_line << "' due to "
                 << "filter_in=" << contents << ".";
    return true;
  }
  return false;
}

// Determine if the filter-out file tells us to skip
static bool SkipForFilterOut(std::string command_line) {
  base::FilePath file =
      paths::GetAt(paths::kSystemRunStateDirectory, paths::kFilterOutFile);
  if (!base::PathExists(file)) {
    return false;
  }

  std::string contents;
  if (!base::ReadFileToString(file, &contents)) {
    LOG(WARNING) << "Failed to read " << file;
    return false;
  }

  if (command_line.find(contents) != std::string::npos) {
    // Matches, so skip this crash.
    LOG(WARNING) << "Ignoring crash invocation '" << command_line << "' due to "
                 << "filter_out=" << contents << ".";
    return true;
  }
  return false;
}

bool SkipCrashCollection(int argc, const char* const argv[]) {
  // Don't skip crashes on real Chromebooks; this is for testing.
  // We can't use IsTestImage because that's always false if a crash test is in
  // progress.
  if (!IsReallyTestImage()) {
    return false;
  }

  std::vector<std::string> args(argv + 1, argv + argc);
  std::string command_line = base::JoinString(args, " ");

  // If the command line consists solely of these flags, it's always allowed
  // (regardless of filter-in state).
  // These flags are always accepted because they do not create crash files.
  // Tests may wish to verify or depend on their effects while also blocking all
  // crashes (using a filter-in of "none").
  const std::vector<std::string> allowlist = {
      "--init",
      "--clean_shutdown",
      "--log_to_stderr",
  };

  bool all_args_allowed = true;
  for (auto it = args.begin(); it != args.end() && all_args_allowed; ++it) {
    if (std::find(allowlist.begin(), allowlist.end(), *it) == allowlist.end()) {
      all_args_allowed = false;
    }
  }
  if (all_args_allowed) {
    return false;
  }

  return SkipForFilterIn(command_line) || SkipForFilterOut(command_line);
}

bool SetGroupAndPermissions(const base::FilePath& file,
                            const char* group,
                            bool execute) {
  gid_t gid;
  if (!brillo::userdb::GetGroupInfo(group, &gid)) {
    LOG(ERROR) << "Couldn't look up group " << group;
    return false;
  }
  if (lchown(file.value().c_str(), -1, gid) != 0) {
    PLOG(ERROR) << "Couldn't chown " << file.value();
    return false;
  }
  int mode;
  if (!base::GetPosixFilePermissions(file, &mode)) {
    PLOG(ERROR) << "Couldn't get file permissions for " << file.value();
    return false;
  }
  mode_t group_mode = S_IRGRP | S_IWGRP;
  if (execute) {
    group_mode |= S_IXGRP;
  }
  if (!base::SetPosixFilePermissions(file, mode | group_mode)) {
    PLOG(ERROR) << "Couldn't chmod " << file.value();
    return false;
  }
  return true;
}

base::Time GetOsTimestamp() {
  base::FilePath lsb_release_path =
      paths::Get(paths::kEtcDirectory).Append(paths::kLsbRelease);
  base::File::Info info;
  if (!base::GetFileInfo(lsb_release_path, &info)) {
    LOG(ERROR) << "Failed reading info for /etc/lsb-release";
    return base::Time();
  }

  return info.last_modified;
}

bool IsBuildTimestampTooOldForUploads(int64_t build_time_millis,
                                      base::Clock* clock) {
  if (build_time_millis == 0) {
    return true;
  } else if (build_time_millis < 0) {
    LOG(ERROR) << "build timestamp is negative: " << build_time_millis;
    return false;
  }
  base::Time timestamp(base::Time::UnixEpoch() +
                       base::TimeDelta::FromMilliseconds(build_time_millis));
  if (timestamp.is_null()) {
    return false;
  }
  base::Time now = clock->Now();
  // In case of invalid timestamps, always upload a crash -- something strange
  // is happening.
  if (timestamp > now) {
    LOG(ERROR) << "OS timestamp is in the future: " << timestamp;
    return false;
  } else if (timestamp < base::Time::UnixEpoch()) {
    LOG(ERROR) << "OS timestamp is negative: " << timestamp;
    return false;
  }
  return (now - timestamp) > kAgeForNoUploads;
}

std::string GetHardwareClass() {
  std::string hw_class;
  if (base::ReadFileToString(paths::Get(kHwClassPath), &hw_class))
    return hw_class;
  auto vb_value = crossystem::GetInstance()->VbGetSystemPropertyString("hwid");
  return vb_value ? vb_value.value() : "undefined";
}

std::string GetBootModeString() {
  // If we're testing crash reporter itself, we don't want to special-case
  // for developer mode.
  if (IsCrashTestInProgress())
    return "";

  auto vb_value = crossystem::GetInstance()->VbGetSystemPropertyInt(kDevSwBoot);
  if (!vb_value) {
    LOG(ERROR) << "Error trying to determine boot mode";
    return "missing-crossystem";
  }
  if (vb_value.value() == 1)
    return kDevMode;

  return "";
}

bool GetCachedKeyValue(const base::FilePath& base_name,
                       const std::string& key,
                       const std::vector<base::FilePath>& directories,
                       std::string* value) {
  std::vector<std::string> error_reasons;
  for (const auto& directory : directories) {
    const base::FilePath file_name = directory.Append(base_name);
    if (!base::PathExists(file_name)) {
      error_reasons.push_back(file_name.value() + " not found");
      continue;
    }
    brillo::KeyValueStore store;
    if (!store.Load(file_name)) {
      LOG(WARNING) << "Problem parsing " << file_name.value();
      // Even though there was some failure, take as much as we could read.
    }
    if (!store.GetString(key, value)) {
      error_reasons.push_back("Key not found in " + file_name.value());
      continue;
    }
    return true;
  }
  LOG(WARNING) << "Unable to find " << key << ": "
               << base::JoinString(error_reasons, ", ");
  return false;
}

bool GetCachedKeyValueDefault(const base::FilePath& base_name,
                              const std::string& key,
                              std::string* value) {
  const std::vector<base::FilePath> kDirectories = {
      paths::Get(paths::kCrashReporterStateDirectory),
      paths::Get(paths::kEtcDirectory),
  };
  return GetCachedKeyValue(base_name, key, kDirectories, value);
}

bool GetUserHomeDirectories(
    org::chromium::SessionManagerInterfaceProxyInterface* session_manager_proxy,
    std::vector<base::FilePath>* directories) {
  brillo::ErrorPtr error;
  std::map<std::string, std::string> sessions;
  session_manager_proxy->RetrieveActiveSessions(&sessions, &error);

  if (error) {
    LOG(ERROR) << "Error calling D-Bus proxy call to interface "
               << "'" << session_manager_proxy->GetObjectPath().value()
               << "': " << error->GetMessage();
    return false;
  }

  for (const auto& iter : sessions) {
    directories->push_back(paths::Get(
        brillo::cryptohome::home::GetHashedUserPath(iter.second).value()));
  }

  return true;
}

bool GetUserCrashDirectories(
    org::chromium::SessionManagerInterfaceProxyInterface* session_manager_proxy,
    std::vector<base::FilePath>* directories) {
  std::vector<base::FilePath> home_directories;
  if (!GetUserHomeDirectories(session_manager_proxy, &home_directories)) {
    return false;
  }

  for (const auto& iter : home_directories) {
    directories->push_back(iter.Append("crash"));
  }

  return true;
}

bool GetDaemonStoreCrashDirectories(
    org::chromium::SessionManagerInterfaceProxyInterface* session_manager_proxy,
    std::vector<base::FilePath>* directories) {
  brillo::ErrorPtr error;
  std::map<std::string, std::string> sessions;
  session_manager_proxy->RetrieveActiveSessions(&sessions, &error);

  if (error) {
    LOG(ERROR) << "Error calling D-Bus proxy call to interface "
               << "'" << session_manager_proxy->GetObjectPath().value()
               << "': " << error->GetMessage();
    return false;
  }

  for (const auto& iter : sessions) {
    directories->push_back(
        paths::Get(base::FilePath(paths::kCryptohomeCrashDirectory)
                       .Append(iter.second)
                       .value()));
  }

  return true;
}

std::vector<unsigned char> GzipStream(brillo::StreamPtr data) {
  // Adapted from https://zlib.net/zlib_how.html
  z_stream deflate_stream;
  memset(&deflate_stream, 0, sizeof(deflate_stream));
  deflate_stream.zalloc = Z_NULL;
  deflate_stream.zfree = Z_NULL;

  // Using a window size of 31 sets us to gzip mode (16) + default window size
  // (15).
  const int kDefaultWindowSize = 15;
  const int kWindowSizeGzipAdd = 16;
  const int kDefaultMemLevel = 8;
  int result = deflateInit2(&deflate_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
                            kDefaultWindowSize + kWindowSizeGzipAdd,
                            kDefaultMemLevel, Z_DEFAULT_STRATEGY);
  if (result != Z_OK) {
    LOG(ERROR) << "Error initializing zlib: error code " << result
               << ", error msg: "
               << (deflate_stream.msg == nullptr ? "None" : deflate_stream.msg);
    return std::vector<unsigned char>();
  }

  std::vector<unsigned char> deflated;
  int flush = Z_NO_FLUSH;
  /* compress until end of stream */
  do {
    size_t read_size = 0;
    unsigned char in[kBufferSize];
    if (!data->ReadBlocking(in, kBufferSize, &read_size, nullptr)) {
      // We are reading from a memory stream, so this really shouldn't happen.
      LOG(ERROR) << "Error reading from input stream";
      deflateEnd(&deflate_stream);
      return std::vector<unsigned char>();
    }
    if (data->GetRemainingSize() <= 0) {
      // We must request a flush on the last chunk of data, else deflateEnd
      // may just discard some compressed data.
      flush = Z_FINISH;
    }
    deflate_stream.next_in = in;
    deflate_stream.avail_in = read_size;
    do {
      unsigned char out[kBufferSize];
      deflate_stream.avail_out = kBufferSize;
      deflate_stream.next_out = out;
      result = deflate(&deflate_stream, flush);
      // Note that most return values are acceptable; don't error out if result
      // is not Z_OK. See discussion at https://zlib.net/zlib_how.html
      DCHECK_NE(result, Z_STREAM_ERROR);
      DCHECK_LE(deflate_stream.avail_out, kBufferSize);
      int amount_in_output_buffer = kBufferSize - deflate_stream.avail_out;
      deflated.insert(deflated.end(), out, out + amount_in_output_buffer);
    } while (deflate_stream.avail_out == 0);
    DCHECK_EQ(deflate_stream.avail_in, 0) << "deflate did not consume all data";
  } while (flush != Z_FINISH);
  DCHECK_EQ(result, Z_STREAM_END) << "Stream did not complete properly";
  deflateEnd(&deflate_stream);
  return deflated;
}

int RunAndCaptureOutput(brillo::ProcessImpl* process,
                        int fd,
                        std::string* output) {
  process->RedirectUsingPipe(fd, false);
  if (process->Start()) {
    const int out = process->GetPipe(fd);
    char buffer[kBufferSize];
    output->clear();

    while (true) {
      const ssize_t count = HANDLE_EINTR(read(out, buffer, kBufferSize));
      if (count < 0) {
        process->Wait();
        break;
      }

      if (count == 0)
        return process->Wait();

      output->append(buffer, count);
    }
  }

  return -1;
}

void LogMultilineError(const std::string& error) {
  std::vector<base::StringPiece> lines = base::SplitStringPiece(
      error, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  for (auto line : lines)
    LOG(ERROR) << line;
}

bool ReadMemfdToString(int mem_fd, std::string* contents) {
  if (contents)
    contents->clear();
  base::ScopedFILE file(fdopen(mem_fd, "r"));
  if (!file) {
    PLOG(ERROR) << "Failed to fdopen(" << mem_fd << ")";
    return false;
  }
  if (fseeko(file.get(), 0, SEEK_END) != 0) {
    PLOG(ERROR) << "fseeko() error";
    return false;
  }
  off_t file_size = ftello(file.get());
  if (file_size < 0) {
    PLOG(ERROR) << "ftello() error";
    return false;
  } else if (file_size == 0) {
    LOG(ERROR) << "Minidump memfd has size of 0";
    return false;
  }

  if (fseeko(file.get(), 0, SEEK_SET) != 0) {
    PLOG(ERROR) << "fseeko() error";
    return false;
  }

  std::unique_ptr<char[]> buf(new char[file_size]);
  if (fread(buf.get(), 1, file_size, file.get()) != file_size) {
    PLOG(ERROR) << "fread() error";
    return false;
  }
  if (contents)
    contents->assign(buf.get(), file_size);

  return true;
}

int GetSelinuxWeight() {
  return 1000;
}

int GetServiceFailureWeight() {
  return 1000;
}

int GetSuspendFailureWeight() {
  return 50;
}

int GetKernelWarningWeight(const std::string& flag) {
  // Sample kernel wifi warnings at a higher weight, since they're heavily
  // environmentally influenced.
  // Sample iwlwifi errors and ath10k errors using a higher weight since they're
  // not as useful and are only actionable for WiFi vendors.
  if (flag == "--kernel_wifi_warning" || flag == "--kernel_ath10k_error" ||
      flag == "--kernel_iwlwifi_error") {
    return 50;
  } else if (flag == "--kernel_warning" || flag == "--kernel_suspend_warning") {
    return 10;
  } else {
    return 1;  // e.g. kernel_smmu_fault
  }
}

int GetUmountStatefulFailureWeight() {
  return 10;
}

bool ReadFdToStream(unsigned int fd, std::stringstream* stream) {
  base::File src(fd);
  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);
  }
}

#if USE_DIRENCRYPTION
void JoinSessionKeyring() {
  key_serial_t session_keyring = keyctl_join_session_keyring(kDircrypt);
  if (session_keyring == -1) {
    // The session keyring may not exist if ext4 encryption isn't enabled so
    // just log an info message instead of an error.
    PLOG(INFO) << "Unable to join session keying";
  }
}
#endif  // USE_DIRENCRYPTION

// Hash a string to a number.  We define our own hash function to not
// be dependent on a C++ library that might change.  This function
// uses basically the same approach as tr1/functional_hash.h but with
// a larger prime number (16127 vs 131).
unsigned HashString(base::StringPiece input) {
  unsigned hash = 0;
  for (auto c : input)
    hash = hash * 16127 + c;
  return hash;
}

base::FilePath GetPathToThisBinary(const char* const argv[]) {
  // To support usage with lddtree, allow overriding argv[0] with the LD_ARGV0
  // environment variable set by lddtree wrappers. Without this, core_pattern
  // will include a .elf suffix, bypassing the lddtree wrapper, leaving
  // crash_reporter unable to start in response to crashes.
  //
  // TODO(crbug.com/1003841): Remove LD_ARGV0 once ld.so supports forwarding
  // the binary name.
  const char* arg0 = getenv("LD_ARGV0");
  if (arg0 == nullptr || arg0[0] == '\0') {
    arg0 = argv[0];
  }
  return base::MakeAbsoluteFilePath(base::FilePath(arg0));
}

}  // namespace util
