| // 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 |