// Copyright 2022 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 "installer/efivar.h"

#include <cstring>
#include <optional>

#include <base/logging.h>
#include <base/strings/string_number_conversions.h>

// TODO(tbrandston): upstream extern "C" to efivar.
// https://github.com/rhboot/efivar/issues/205
extern "C" {
#include "efivar/efiboot.h"
}

namespace {
bool IsEfiGlobalGUID(const efi_guid_t* guid) {
  const efi_guid_t global = EFI_GLOBAL_GUID;
  return memcmp(guid, &global, sizeof(global)) == 0;
}

// Wrapper around the libefivar error logging interface.
//
// libefivar stores a list of errors that it encounters, and lets you access
// them by index. The list is cleared when certain calls succeed, but successive
// errors can accumulate.
//
// This accumulation can make for confusing logs if we only clear these logs
// after libefivar functions return failure.
// For example, GenerateFileDevicePathFromEsp may produce a pair of errors like:
// ./util.h:325:get_file rc=1 could not open file "/sys/devices/pci0000:00/..."
// but efi_generate_file_device_path_from_esp still returns success. If we don't
// clear those errors they'll show up the next time we look at logged errors,
// which will be after an unrelated call.
//
// To simplify logging and clearing, and ensure that all returns will clear,
// this wrapper logs all errors and clears the list on destruction. Instantiate
// a local instance in each function that calls a libefivar function.
class EfiLogWrapper {
 public:
  explicit EfiLogWrapper(const std::string& source) : source_(source) {
    // Clear any errors encountered before construction to avoid confusion.
    efi_error_clear();
  }

  ~EfiLogWrapper() {
    // Log all errors upon destruction.
    LogEfiErrors();
    efi_error_clear();
  }

  // Log all libefivar errors.
  void LogEfiErrors() {
    uint32_t index = 0;

    char* filename = nullptr;
    char* function = nullptr;
    int line = 0;
    char* message = nullptr;
    int error = 0;

    while (true) {
      int rc =
          efi_error_get(index, &filename, &function, &line, &message, &error);

      if (rc == -1) {
        LOG(ERROR) << "programmer error, invalid args.";
        return;
      } else if (rc == 0) {
        // No more errors, for now.
        break;
      }

      // We don't know here whether it should be treated as a warning or an
      // error, so we'll call everything a warning and let further logging
      // clarify.
      LOG(WARNING) << source_ << "triggered efi error " << index << ": "
                   << filename << ":" << line << ":" << function << " rc=" << rc
                   << " " << message << ": " << std::strerror(error);
      index += 1;
    }
  }

  // Get the errno stored in the libefivar log at index 0.
  // This is the first one encountered and the most likely to be relevant.
  std::optional<EfiVarError> GetFirstErrno() {
    const uint32_t idx = 0;
    char* file = nullptr;
    char* func = nullptr;
    int line = 0;
    char* message = nullptr;
    int error_num = 0;

    if (efi_error_get(idx, &file, &func, &line, &message, &error_num) == 1) {
      return error_num;
    }

    return std::nullopt;
  }

 private:
  // Where this was instantiated, to help clarify where errors are coming from.
  std::string source_;
};

}  // namespace

const uint32_t kBootVariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
                                         EFI_VARIABLE_RUNTIME_ACCESS |
                                         EFI_VARIABLE_NON_VOLATILE;

std::string EfiVarInterface::LoadoptDesc(uint8_t* const data,
                                         size_t data_size) {
  EfiLogWrapper log_wrapper(__func__);
  efi_load_option* load_opt = reinterpret_cast<efi_load_option*>(data);

  // Memory returned by efi_loadopt_desc doesn't need to be freed.
  // Internally it frees the previously loaded description each time you
  // load a new one.
  const unsigned char* unsigned_desc = efi_loadopt_desc(load_opt, data_size);

  // Store the unsigned chars in signed chars for ease of use outside this api.
  return reinterpret_cast<const char*>(unsigned_desc);
}

std::vector<uint8_t> EfiVarInterface::LoadoptPath(uint8_t* const data,
                                                  size_t data_size) {
  EfiLogWrapper log_wrapper(__func__);
  efi_load_option* load_opt = reinterpret_cast<efi_load_option*>(data);

  // This path_data is just a pointer into `data`, not separately allocated.
  efidp path_data = efi_loadopt_path(load_opt, data_size);
  const ssize_t path_data_size = efi_loadopt_pathlen(load_opt, data_size);

  // Copy the path data into a vector.
  return std::vector<uint8_t>(
      reinterpret_cast<uint8_t*>(path_data),
      reinterpret_cast<uint8_t*>(path_data) + path_data_size);
}

bool EfiVarInterface::LoadoptCreate(uint32_t loadopt_attributes,
                                    std::vector<uint8_t>& efidp_data,
                                    std::string& description,
                                    std::vector<uint8_t>* data) {
  EfiLogWrapper log_wrapper(__func__);
  efidp device_path = reinterpret_cast<efidp>(efidp_data.data());
  unsigned char* description_data =
      reinterpret_cast<unsigned char*>(description.data());

  // Passing a size of 0 will simply return the sum of the lengths of the
  // relevant arguments, which tells us how much space to allocate.
  const ssize_t entry_data_size =
      efi_loadopt_create(nullptr, 0, loadopt_attributes, device_path,
                         efidp_data.size(), description_data,
                         // optional, for EDD10 or something?
                         nullptr, 0);

  data->resize(entry_data_size);

  const ssize_t rv = efi_loadopt_create(
      data->data(), entry_data_size, loadopt_attributes, device_path,
      efidp_data.size(), description_data, nullptr, 0);

  if (rv < 0) {
    LOG(ERROR) << "Error formatting data for efi variable.\n"
               << "attributes: " << loadopt_attributes << "\n"
               << "efidp_data: "
               << base::HexEncode(efidp_data.data(), efidp_data.size()) << "\n"
               << "description: " << description << "\n";

    return false;
  }

  return true;
}

bool EfiVarImpl::EfiVariablesSupported() {
  return efi_variables_supported();
}

std::optional<std::string> EfiVarImpl::GetNextVariableName() {
  EfiLogWrapper log_wrapper(__func__);

  efi_guid_t* guid = nullptr;
  char* name = nullptr;
  int rc = 0;

  // efi_get_next_variable_name repeatedly returns the same static char[].
  // efi_get_next_variable_name returns 1 if an entry is found.
  while ((rc = efi_get_next_variable_name(&guid, &name)) > 0) {
    // NULL is not expected but guard against it.
    if (!name || !guid)
      return std::nullopt;
    if (!IsEfiGlobalGUID(guid))
      continue;
    return std::string(name);
  }

  return std::nullopt;
}

bool EfiVarImpl::GetVariable(const std::string& name,
                             Bytes& data,
                             size_t* data_size) {
  EfiLogWrapper log_wrapper(__func__);

  // efi_get_variable will malloc some space and store it in `data`,
  // so we have to make sure it gets freed.
  uint8_t* data_ptr;

  // All the variables we manage have well defined attributes by the efi spec,
  // so we can safely ignore these -- if they're somehow different we'd want to
  // fix them.
  uint32_t ignored_attributes;

  if (efi_get_variable(EFI_GLOBAL_GUID, name.c_str(), &data_ptr, data_size,
                       &ignored_attributes) < 0) {
    LOG(ERROR) << "Error getting '" << name << "'";
    // Okay to return without freeing data if ret < 0 (at least in the
    // current (v37) efivar implementation ...).
    return false;
  }

  // Pass data out, ensuring it gets freed when it's no longer needed.
  data.reset(data_ptr);

  return true;
}

std::optional<EfiVarError> EfiVarImpl::SetVariable(const std::string& name,
                                                   uint32_t attributes,
                                                   std::vector<uint8_t>& data) {
  EfiLogWrapper log_wrapper(__func__);

  if (efi_set_variable(EFI_GLOBAL_GUID, name.c_str(), data.data(), data.size(),
                       attributes,
                       // mode
                       0644) < 0) {
    LOG(ERROR) << "Error setting '" << name
               << "' data: " << base::HexEncode(data.data(), data.size());
    return log_wrapper.GetFirstErrno();
  }

  return std::nullopt;
}

bool EfiVarImpl::DelVariable(const std::string& name) {
  EfiLogWrapper log_wrapper(__func__);
  if (efi_del_variable(EFI_GLOBAL_GUID, name.c_str()) < 0) {
    LOG(ERROR) << "Error deleting '" << name << "'";
    return false;
  }

  return true;
}

bool EfiVarImpl::GenerateFileDevicePathFromEsp(
    const std::string& device_path,
    int esp_partition,
    const std::string& boot_file,
    std::vector<uint8_t>& efidp_data) {
  EfiLogWrapper log_wrapper(__func__);

  // Check how much capacity we'll need in efidp by passing null/0 first.
  const ssize_t required_size = efi_generate_file_device_path_from_esp(
      nullptr, 0, device_path.c_str(), esp_partition, boot_file.c_str(),
      EFIBOOT_ABBREV_HD);

  if (required_size < 0) {
    LOG(ERROR) << "Could not generate device path. "
               << "efi_generate_file_device_path_from_esp returned: "
               << required_size;
    return false;
  }

  efidp_data.resize(required_size);

  const ssize_t rv = efi_generate_file_device_path_from_esp(
      efidp_data.data(), required_size, device_path.c_str(), esp_partition,
      boot_file.c_str(), EFIBOOT_ABBREV_HD);

  if (rv < 0) {
    LOG(ERROR) << "Could not generate device path. "
               << "efi_generate_file_device_path_from_esp returned: " << rv;
    return false;
  }

  return true;
}
