blob: 2071a095adfa81e7cb4fe590b0acc776e2508db5 [file] [log] [blame] [edit]
// Copyright 2020 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "biod/updater/update_utils.h"
#include <optional>
#include <string>
#include <string_view>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <brillo/vcsid.h>
#include <cros_config/cros_config_interface.h>
#include "biod/biod_config.h"
namespace {
constexpr char kFirmwareGlobSuffix[] = "_*.bin";
constexpr char kUpdateDisableFile[] =
"/var/lib/bio_fw_updater/.disable_fp_updater";
} // namespace
namespace biod {
namespace updater {
std::string UpdaterVersion() {
static_assert(brillo::kVCSID,
"The updater requires VCSID to function properly.");
return std::string(*brillo::kVCSID);
}
bool UpdateDisallowed(const BiodSystem& system) {
// Disable updates when /var/lib/bio_fw_updater/.disable_fp_updater exists
// and Developer Mode can boot from unsigned kernel (it's a bit stronger check
// than developer mode only).
if (!system.OnlyBootSignedKernel() &&
base::PathExists(base::FilePath(kUpdateDisableFile))) {
return true;
}
return false;
}
FindFirmwareFileStatus FindFirmwareFile(
const base::FilePath& directory,
brillo::CrosConfigInterface* cros_config,
base::FilePath* file) {
std::optional<std::string> board_name = biod::FingerprintBoard(cros_config);
if (!board_name.has_value() || board_name->empty()) {
LOG(ERROR) << "Fingerprint board name is unavailable";
return FindFirmwareFileStatus::kBoardUnavailable;
}
LOG(INFO) << "Identified fingerprint board name as '" << *board_name << "'.";
if (!base::DirectoryExists(directory)) {
return FindFirmwareFileStatus::kNoDirectory;
}
std::string glob(*board_name + std::string(kFirmwareGlobSuffix));
base::FileEnumerator fw_bin_list(directory, false,
base::FileEnumerator::FileType::FILES, glob);
// Find provided firmware file
base::FilePath fw_bin = fw_bin_list.Next();
if (fw_bin.empty()) {
return FindFirmwareFileStatus::kFileNotFound;
}
LOG(INFO) << "Found firmware file '" << fw_bin.value() << "'.";
// Ensure that there are no other firmware files
bool extra_fw_files = false;
for (base::FilePath fw_extra = fw_bin_list.Next(); !fw_extra.empty();
fw_extra = fw_bin_list.Next()) {
extra_fw_files = true;
LOG(ERROR) << "Found firmware file '" << fw_extra.value() << "'.";
}
if (extra_fw_files) {
return FindFirmwareFileStatus::kMultipleFiles;
}
*file = fw_bin;
return FindFirmwareFileStatus::kFoundFile;
}
std::string FindFirmwareFileStatusToString(FindFirmwareFileStatus status) {
switch (status) {
case FindFirmwareFileStatus::kFoundFile:
return "Firmware file found.";
case FindFirmwareFileStatus::kNoDirectory:
return "Firmware directory does not exist.";
case FindFirmwareFileStatus::kFileNotFound:
return "Firmware file not found.";
case FindFirmwareFileStatus::kMultipleFiles:
return "More than one firmware file was found.";
case FindFirmwareFileStatus::kBoardUnavailable:
return "Fingerprint board name is not available.";
}
NOTREACHED();
return "Unknown find firmware file status encountered.";
}
} // namespace updater
} // namespace biod