From 327237d13a34af622607268bc9f363d4dec2bc24 Mon Sep 17 00:00:00 2001 From: Tianjie Date: Wed, 20 Jan 2021 19:02:34 -0800 Subject: [PATCH] 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 --- fs_mgr/fs_mgr.cpp | 35 +++++++++++++++++++++++++++++++++++ fs_mgr/include/fs_mgr.h | 4 ++++ init/builtins.cpp | 5 +++++ 3 files changed, 44 insertions(+) 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 {};