// Copyright 2017 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/bert_collector.h"

#include <fcntl.h>
#include <string>
#include <sys/stat.h>

#include <base/files/file_util.h>
#include <base/logging.h>

#include "crash-reporter/util.h"

using base::FilePath;

namespace {

constexpr char kACPITablePath[] = "/sys/firmware/acpi/tables";
constexpr char kBertTable[] = "BERT";
constexpr char kBertData[] = "data/BERT";
constexpr char kBertErrorName[] = "bert_error";

// Validate BERT table signature, length and region length.
bool BertCheckTable(const struct acpi_table_bert& bert_table) {
  if (memcmp(bert_table.signature, ACPI_SIG_BERT, ACPI_NAME_SIZE) != 0)
    return false;
  if (bert_table.length != sizeof(struct acpi_table_bert))
    return false;
  if (bert_table.region_length != 0 &&
      bert_table.region_length < ACPI_BERT_REGION_STRUCT_SIZE)
    return false;

  return true;
}

// Read BERT table and data files.
// BERT stores data in little endian, and we assume the CPU endian is
// also little endian.
bool BertRead(const FilePath& bert_table_path,
              const FilePath& bert_data_path,
              struct acpi_table_bert* bert_table,
              std::string* bert_table_contents,
              std::string* bert_data_contents) {
  // Read BERT table file.
  if (!base::ReadFileToStringWithMaxSize(bert_table_path,
                                         bert_table_contents,
                                         sizeof(struct acpi_table_bert))) {
    PLOG(ERROR) << "BERT table file read failed";
    return false;
  }
  memcpy(bert_table, bert_table_contents->data(), sizeof(*bert_table));

  if (!BertCheckTable(*bert_table)) {
    LOG(ERROR) << "Bad data in BERT table";
    return false;
  }

  // Read BERT data file.
  if (!base::ReadFileToStringWithMaxSize(bert_data_path,
                                         bert_data_contents,
                                         bert_table->region_length)) {
    PLOG(ERROR) << "BERT data file read failed";
    return false;
  }
  return true;
}

}  // namespace

BERTCollector::BERTCollector()
    : CrashCollector("bert"), acpitable_path_(kACPITablePath) {}

BERTCollector::~BERTCollector() {}

bool BERTCollector::Collect() {
  FilePath root_crash_directory;

  const FilePath bert_table_path = acpitable_path_.Append(kBertTable);
  if (!base::PathExists(bert_table_path)) {
    return false;
  }

  const FilePath bert_data_path = acpitable_path_.Append(kBertData);
  if (!base::PathExists(bert_data_path)) {
    PLOG(ERROR) << bert_data_path.value() << " sysfs data not available";
    return false;
  }

  std::string reason = "handling";
  bool feedback = true;
  if (util::IsDeveloperImage()) {
    reason = "developer build - always dumping";
    feedback = true;
  } else if (!is_feedback_allowed_function_()) {
    reason = "ignoring - no consent";
    feedback = false;
  }
  LOG(INFO) << "BERT error from previous boot (" << reason << ")";
  if (!feedback) {
    return true;
  }

  std::string bert_table_contents;
  std::string bert_data_contents;
  struct acpi_table_bert bert_table;
  // Read BERT table and BERT data information.
  if (!BertRead(bert_table_path, bert_data_path, &bert_table,
                &bert_table_contents, &bert_data_contents)) {
    return false;
  }

  // Dump BERT table and BERT data into single bertdump file.
  if (!GetCreatedCrashDirectoryByEuid(kRootUid,
                                      &root_crash_directory,
                                      nullptr)) {
    return false;
  }
  std::string dump_basename =
      FormatDumpBasename(kBertErrorName, time(nullptr), 0);
  FilePath bert_crash_path = GetCrashPath(
      root_crash_directory, dump_basename, "bertdump");

  // We must use WriteNewFile instead of base::WriteFile as we
  // do not want to write with root access to a symlink that an attacker
  // might have created.
  if (WriteNewFile(bert_crash_path, bert_table_contents.c_str(),
                   bert_table.length) != bert_table.length) {
    PLOG(ERROR) << "Failed to write BERT table to "
                << bert_crash_path.value();
    return false;
  }
  if (!base::AppendToFile(bert_crash_path,
                          bert_data_contents.c_str(),
                          bert_table.region_length)) {
    PLOG(ERROR) << "Failed to write BERT data to "
                << bert_crash_path.value();
    return false;
  }

  // Create meta file with bert dump info and finish up.
  FinishCrash(GetCrashPath(root_crash_directory, dump_basename, "meta"),
              kBertErrorName, bert_crash_path.value());

  VLOG(3) << "Stored BERT dump to " << bert_crash_path.value();

  return true;
}
