bool generate_verity_tree(const std::string& data_filename, const std::string& verity_filename, HashTreeBuilder* builder, const std::vector<unsigned char>& salt_content, size_t block_size, bool sparse, bool verbose) { android::base::unique_fd data_fd(open(data_filename.c_str(), O_RDONLY)); if (data_fd == -1) { PLOG(ERROR) << "failed to open " << data_filename; return false; } struct sparse_file* file; if (sparse) { file = sparse_file_import(data_fd, false, false); } else { file = sparse_file_import_auto(data_fd, false, verbose); } if (!file) { LOG(ERROR) << "failed to read file " << data_filename; return false; } int64_t len = sparse_file_len(file, false, false); if (len % block_size != 0) { LOG(ERROR) << "file size " << len << " is not a multiple of " << block_size << " byte"; return false; } // Initialize the builder to compute the hash tree. if (!builder->Initialize(len, salt_content)) { LOG(ERROR) << "Failed to initialize HashTreeBuilder"; return false; } auto hash_callback = [](void* priv, const void* data, size_t len) { auto sparse_hasher = static_cast<HashTreeBuilder*>(priv); return sparse_hasher->Update(static_cast<const unsigned char*>(data), len) ? 0 : 1; }; sparse_file_callback(file, false, false, hash_callback, builder); sparse_file_destroy(file); if (!builder->BuildHashTree()) { return false; } return builder->WriteHashTreeToFile(verity_filename); }
static void ProcessFirmwareEvent(const Uevent& uevent) { int booting = IsBooting(); LOG(INFO) << "firmware: loading '" << uevent.firmware << "' for '" << uevent.path << "'"; std::string root = "/sys" + uevent.path; std::string loading = root + "/loading"; std::string data = root + "/data"; unique_fd loading_fd(open(loading.c_str(), O_WRONLY | O_CLOEXEC)); if (loading_fd == -1) { PLOG(ERROR) << "couldn't open firmware loading fd for " << uevent.firmware; return; } unique_fd data_fd(open(data.c_str(), O_WRONLY | O_CLOEXEC)); if (data_fd == -1) { PLOG(ERROR) << "couldn't open firmware data fd for " << uevent.firmware; return; } static const char* firmware_dirs[] = {"/etc/firmware/", "/vendor/firmware/", "/firmware/image/"}; try_loading_again: for (size_t i = 0; i < arraysize(firmware_dirs); i++) { std::string file = firmware_dirs[i] + uevent.firmware; unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC)); struct stat sb; if (fw_fd != -1 && fstat(fw_fd, &sb) != -1) { LoadFirmware(uevent, root, fw_fd, sb.st_size, loading_fd, data_fd); return; } } if (booting) { // If we're not fully booted, we may be missing // filesystems needed for firmware, wait and retry. std::this_thread::sleep_for(100ms); booting = IsBooting(); goto try_loading_again; } LOG(ERROR) << "firmware: could not find firmware for " << uevent.firmware; // Write "-1" as our response to the kernel's firmware request, since we have nothing for it. write(loading_fd, "-1", 2); }