diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 2876094be..1efe793a5 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -2143,6 +2143,41 @@ bool fs_mgr_is_verity_enabled(const FstabEntry& entry) { return false; } +std::string fs_mgr_get_hashtree_algorithm(const android::fs_mgr::FstabEntry& entry) { + if (!entry.fs_mgr_flags.verify && !entry.fs_mgr_flags.avb) { + return ""; + } + DeviceMapper& dm = DeviceMapper::Instance(); + std::string device = GetVerityDeviceName(entry); + + std::vector table; + if (dm.GetState(device) == DmDeviceState::INVALID || !dm.GetTableInfo(device, &table)) { + return ""; + } + for (const auto& target : table) { + if (strcmp(target.spec.target_type, "verity") != 0) { + continue; + } + + // The format is stable for dm-verity version 0 & 1. And the data is expected to have + // the fixed format: + // + // + // Details in https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html + + std::vector tokens = android::base::Split(target.data, " \t\r\n"); + if (tokens[0] != "0" && tokens[0] != "1") { + LOG(WARNING) << "Unrecognized device mapper version in " << target.data; + return ""; + } + + // Hashtree algorithm is the 8th token in the output + return android::base::Trim(tokens[7]); + } + + return ""; +} + bool fs_mgr_verity_is_check_at_most_once(const android::fs_mgr::FstabEntry& entry) { if (!entry.fs_mgr_flags.verify && !entry.fs_mgr_flags.avb) { return false; diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index 11e36645e..22c02ccf8 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -88,6 +88,10 @@ int fs_mgr_do_tmpfs_mount(const char *n_name); bool fs_mgr_load_verity_state(int* mode); // Returns true if verity is enabled on this particular FstabEntry. bool fs_mgr_is_verity_enabled(const android::fs_mgr::FstabEntry& entry); +// Returns the hash algorithm used to build the hashtree of this particular FstabEntry. Returns an +// empty string if the input isn't a dm-verity entry, or if there is an error. +std::string fs_mgr_get_hashtree_algorithm(const android::fs_mgr::FstabEntry& entry); + bool fs_mgr_swapon_all(const android::fs_mgr::Fstab& fstab); bool fs_mgr_update_logical_partition(android::fs_mgr::FstabEntry* entry); diff --git a/init/builtins.cpp b/init/builtins.cpp index c44e03ed7..6b7d1e950 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -861,6 +861,11 @@ static Result do_verity_update_state(const BuiltinArguments& args) { // for system as root, so it has property [partition.system.verified]. std::string partition = entry.mount_point == "/" ? "system" : Basename(entry.mount_point); SetProperty("partition." + partition + ".verified", std::to_string(mode)); + + std::string hash_alg = fs_mgr_get_hashtree_algorithm(entry); + if (!hash_alg.empty()) { + SetProperty("partition." + partition + ".verified.hash_alg", hash_alg); + } } return {};