Set hashtree algorithm for verity partitions
This is used in cts tests to verify that algorithms in blocklist aren't
used to build the hashtree. The system properties are required to perform
the check on unrooted devices.
Bug: 175236047
Test: flash, getprop; atest CtsNativeVerifiedBootTestCases
Change-Id: I2dcfdb06f85dbe92cde45e836dd68e7bd835020f
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 2876094..1efe793 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -2143,6 +2143,41 @@
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<DeviceMapper::TargetInfo> 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:
+ // <version> <dev> <hash_dev> <data_block_size> <hash_block_size> <num_data_blocks>
+ // <hash_start_block> <algorithm> <digest> <salt>
+ // Details in https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html
+
+ std::vector<std::string> 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 11e3664..22c02cc 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -88,6 +88,10 @@
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 c44e03e..6b7d1e9 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -861,6 +861,11 @@
// 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 {};