Initialize roothash when populating sig partition

This allows one to specify `CopyBlocks=` on both the `Verity=` data and
hash partition and the signature is recreated correctly.
This commit is contained in:
Michael Ferrari
2026-04-02 13:21:08 +02:00
parent 189d5c020b
commit ecf2329e14
+34 -6
View File
@@ -5788,21 +5788,41 @@ static int sign_verity_roothash(
#endif
}
static const VeritySettings *lookup_verity_settings_by_uuid_pair(sd_id128_t data_uuid, sd_id128_t hash_uuid) {
uint8_t root_hash_key[sizeof(sd_id128_t) * 2];
static int iovec_roothash_from_uuid_pair(
sd_id128_t data_uuid,
sd_id128_t hash_uuid,
struct iovec *ret_roothash) {
uint8_t roothash_bytes[sizeof(sd_id128_t) * 2];
assert(ret_roothash);
if (sd_id128_is_null(data_uuid) || sd_id128_is_null(hash_uuid))
return NULL;
return -EINVAL;
/* As per the https://uapi-group.org/specifications/specs/discoverable_partitions_specification/ the
* UUIDs of the data and verity partitions are respectively the first and second halves of the
* dm-verity roothash, so we can use them to match the signature to the right partition. */
memcpy(root_hash_key, data_uuid.bytes, sizeof(sd_id128_t));
memcpy(root_hash_key + sizeof(sd_id128_t), hash_uuid.bytes, sizeof(sd_id128_t));
memcpy(roothash_bytes, data_uuid.bytes, sizeof(sd_id128_t));
memcpy(roothash_bytes + sizeof(sd_id128_t), hash_uuid.bytes, sizeof(sd_id128_t));
if (!iovec_memdup(&IOVEC_MAKE(roothash_bytes, sizeof(roothash_bytes)), ret_roothash))
return -ENOMEM;
return 0;
}
static const VeritySettings *lookup_verity_settings_by_uuid_pair(sd_id128_t data_uuid, sd_id128_t hash_uuid) {
_cleanup_(iovec_done) struct iovec roothash = {};
int r;
r = iovec_roothash_from_uuid_pair(data_uuid, hash_uuid, &roothash);
if (r < 0)
return NULL;
VeritySettings key = {
.root_hash = IOVEC_MAKE(root_hash_key, sizeof(root_hash_key)),
.root_hash = roothash,
};
return set_get(arg_verity_settings, &key);
@@ -5834,6 +5854,14 @@ static int partition_format_verity_sig(Context *context, Partition *p) {
assert_se(rp = p->siblings[VERITY_DATA]);
assert(!rp->dropped);
/* Currently only set while formatting the hash partition. But if this is skipped via CopyBlocks=
* we just derive the roothash from the UUIDs from the data + hash partition. */
if (!iovec_is_set(&hp->roothash)) {
r = iovec_roothash_from_uuid_pair(rp->new_uuid, hp->new_uuid, &hp->roothash);
if (r < 0)
return log_error_errno(r, "Unable to derive roothash: %m");
}
verity_settings = lookup_verity_settings_by_uuid_pair(rp->current_uuid, hp->current_uuid);
if (!verity_settings) {