1
0
mirror of https://github.com/systemd/systemd synced 2025-10-06 00:13:24 +02:00

dissect: Add more debug logging (#39125)

This commit is contained in:
Daan De Meyer
2025-09-26 11:53:35 +02:00
committed by GitHub
7 changed files with 98 additions and 100 deletions

View File

@@ -2809,7 +2809,7 @@ static int partition_read_definition(Partition *p, const char *path, const char
}
/* Verity partitions are read only, let's imply the RO flag hence, unless explicitly configured otherwise. */
if ((partition_designator_is_verity(p->type.designator) || p->verity == VERITY_DATA) && p->read_only < 0)
if ((partition_designator_is_verity_hash(p->type.designator) || p->verity == VERITY_DATA) && p->read_only < 0)
p->read_only = true;
/* Default to "growfs" on, unless read-only */
@@ -7500,7 +7500,7 @@ static int resolve_copy_blocks_auto_candidate_harder(
* verity/verity-sig partition for it, based on udev metadata. */
const char *property;
if (partition_designator_is_verity(partition_type.designator))
if (partition_designator_is_verity_hash(partition_type.designator))
property = "ID_DISSECT_PART_VERITY_DEVICE";
else if (partition_designator_is_verity_sig(partition_type.designator))
property = "ID_DISSECT_PART_VERITY_SIG_DEVICE";

View File

@@ -1060,9 +1060,31 @@ static int dissect_image(
if (!image_filter_test(filter, type.designator, label))
continue;
log_debug("Dissecting %s partition with label %s and UUID %s",
log_debug("Dissecting %s partition with label %s and UUID %s.",
strna(partition_designator_to_string(type.designator)), strna(label), SD_ID128_TO_UUID_STRING(id));
/* Note that we don't check the SD_GPT_FLAG_NO_AUTO flag for the ESP, as it is
* not defined there. We instead check the SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as
* recommended by the UEFI spec (See "12.3.3 Number and Location of System
* Partitions"). */
if (FLAGS_SET(pflags, SD_GPT_FLAG_NO_AUTO) && type.designator != PARTITION_ESP) {
log_debug("Partition has 'no auto' flag set, ignoring.");
continue;
}
if (!verity && partition_designator_is_verity(type.designator)) {
log_debug("Partition is a verity hash or verity signature partition but no verity was requested, ignoring.");
continue;
}
PartitionDesignator vd = partition_verity_to_data(type.designator);
if (verity && verity->designator >= 0 && vd >= 0 && vd != verity->designator) {
log_debug("Partition is a %s partition but verity was only requested for the %s partition, ignoring.",
partition_designator_to_string(type.designator),
partition_designator_to_string(verity->designator));
continue;
}
if (IN_SET(type.designator,
PARTITION_HOME,
PARTITION_SRV,
@@ -1072,21 +1094,15 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
} else if (type.designator == PARTITION_ESP) {
/* Note that we don't check the SD_GPT_FLAG_NO_AUTO flag for the ESP, as it is
* not defined there. We instead check the SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as
* recommended by the UEFI spec (See "12.3.3 Number and Location of System
* Partitions"). */
if (pflags & SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL)
if (FLAGS_SET(pflags, SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL)) {
log_debug("ESP Partition has 'no block io' flag set, ignoring.");
continue;
}
fstype = "vfat";
@@ -1095,12 +1111,13 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
/* If a root ID is specified, ignore everything but the root id */
if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id)) {
log_debug("Partition UUID '%s' does not match expected UUID '%s' derived from root verity hash, ignoring.",
SD_ID128_TO_UUID_STRING(id),
SD_ID128_TO_UUID_STRING(root_uuid));
continue;
}
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
@@ -1110,20 +1127,15 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
m->has_verity = true;
/* If no verity configuration is specified, then don't do verity */
if (!verity)
continue;
if (verity->designator >= 0 && verity->designator != PARTITION_ROOT)
continue;
/* If root hash is specified, then ignore everything but the root id */
if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id))
if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id)) {
log_debug("Partition UUID '%s' does not match expected UUID '%s' derived from root verity hash, ignoring.",
SD_ID128_TO_UUID_STRING(id),
SD_ID128_TO_UUID_STRING(root_verity_uuid));
continue;
}
fstype = "DM_verity_hash";
rw = false;
@@ -1133,16 +1145,7 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
m->has_verity_sig = true;
if (!verity)
continue;
if (verity->designator >= 0 && verity->designator != PARTITION_ROOT)
continue;
fstype = "verity_hash_signature";
rw = false;
@@ -1151,12 +1154,13 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
/* If a usr ID is specified, ignore everything but the usr id */
if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id))
if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id)) {
log_debug("Partition UUID '%s' does not match expected UUID '%s' derived from usr verity hash, ignoring.",
SD_ID128_TO_UUID_STRING(id),
SD_ID128_TO_UUID_STRING(usr_uuid));
continue;
}
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
@@ -1166,19 +1170,15 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
m->has_verity = true;
if (!verity)
continue;
if (verity->designator >= 0 && verity->designator != PARTITION_USR)
continue;
/* If usr hash is specified, then ignore everything but the usr id */
if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id))
if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id)) {
log_debug("Partition UUID '%s' does not match expected UUID '%s' derived from usr verity hash, ignoring.",
SD_ID128_TO_UUID_STRING(id),
SD_ID128_TO_UUID_STRING(usr_uuid));
continue;
}
fstype = "DM_verity_hash";
rw = false;
@@ -1188,16 +1188,7 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
m->has_verity_sig = true;
if (!verity)
continue;
if (verity->designator >= 0 && verity->designator != PARTITION_USR)
continue;
fstype = "verity_hash_signature";
rw = false;
@@ -1205,9 +1196,6 @@ static int dissect_image(
check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
/* Note: we don't set fstype = "swap" here, because we still need to probe if
* it might be encrypted (i.e. fstype "crypt_LUKS") or unencrypted
* (i.e. fstype "swap"), and the only way to figure that out is via fstype
@@ -1222,9 +1210,6 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
if (generic_node)
multiple_generic = true;
else {
@@ -1240,9 +1225,6 @@ static int dissect_image(
check_partition_flags(node, pflags,
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
if (pflags & SD_GPT_FLAG_NO_AUTO)
continue;
if (!FLAGS_SET(flags, DISSECT_IMAGE_RELAX_VAR_CHECK)) {
sd_id128_t var_uuid;
@@ -1446,12 +1428,12 @@ static int dissect_image(
m->partitions[PARTITION_ROOT_VERITY_SIG].found))
return log_debug_errno(
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Found root verity hash partition without matching root data partition");
"Found root verity hash partition without matching root data partition.");
/* Hmm, we found a signature partition but no Verity data? Something is off. */
if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found)
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Found root verity signature partition without matching root verity hash partition");
"Found root verity signature partition without matching root verity hash partition.");
/* as above */
if (!m->partitions[PARTITION_USR].found &&
@@ -1459,12 +1441,12 @@ static int dissect_image(
m->partitions[PARTITION_USR_VERITY_SIG].found))
return log_debug_errno(
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Found usr verity hash partition without matching usr data partition");
"Found usr verity hash partition without matching usr data partition.");
/* as above */
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Found usr verity signature partition without matching usr verity hash partition");
"Found usr verity signature partition without matching usr verity hash partition.");
/* If root and /usr are combined then insist that the architecture matches */
if (m->partitions[PARTITION_ROOT].found &&
@@ -1473,7 +1455,7 @@ static int dissect_image(
m->partitions[PARTITION_USR].architecture >= 0 &&
m->partitions[PARTITION_ROOT].architecture != m->partitions[PARTITION_USR].architecture))
return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE),
"Found root and usr partitions with different architectures (%s vs %s)",
"Found root and usr partitions with different architectures (%s vs %s).",
architecture_to_string(m->partitions[PARTITION_ROOT].architecture),
architecture_to_string(m->partitions[PARTITION_USR].architecture));
@@ -1543,17 +1525,17 @@ static int dissect_image(
/* Check if we have a root fs if we are told to do check. /usr alone is fine too, but only if appropriate flag for that is set too */
if (FLAGS_SET(flags, DISSECT_IMAGE_REQUIRE_ROOT) &&
!(m->partitions[PARTITION_ROOT].found || (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT))))
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Root or usr partition requested but found neither");
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Root or usr partition requested but found neither.");
if (m->partitions[PARTITION_ROOT_VERITY].found) {
/* We only support one verity partition per image, i.e. can't do for both /usr and root fs */
if (m->partitions[PARTITION_USR_VERITY].found)
return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Found both root and usr verity enabled partitions which is not supported");
return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Found both root and usr verity enabled partitions which is not supported.");
/* We don't support verity enabled root with a split out /usr. Neither with nor without
* verity there. (Note that we do support verity-less root with verity-full /usr, though.) */
if (m->partitions[PARTITION_USR].found)
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL), "Found verity enabled root partition with split usr partition which is not supported");
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL), "Found verity enabled root partition with split usr partition which is not supported.");
}
if (verity) {
@@ -1561,7 +1543,7 @@ static int dissect_image(
if (verity->designator >= 0 && !m->partitions[verity->designator].found)
return log_debug_errno(
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Explicit %s verity designator was specified but did not find %s partition",
"Explicit %s verity designator was specified but did not find %s partition.",
partition_designator_to_string(verity->designator),
partition_designator_to_string(verity->designator));
@@ -1573,12 +1555,12 @@ static int dissect_image(
if (!m->partitions[PARTITION_ROOT].found)
return log_debug_errno(
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Verity enabled root partition was requested but did not find a root data partition");
"Verity enabled root partition was requested but did not find a root data partition.");
if (!m->partitions[PARTITION_ROOT_VERITY].found)
return log_debug_errno(
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Verity enabled root partition was requested but did not find a root verity hash partition");
"Verity enabled root partition was requested but did not find a root verity hash partition.");
/* If we found a verity setup, then the root partition is necessarily read-only. */
m->partitions[PARTITION_ROOT].rw = false;
@@ -1588,12 +1570,12 @@ static int dissect_image(
if (!m->partitions[PARTITION_USR].found)
return log_debug_errno(
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Verity enabled usr partition was requested but did not find a usr data partition");
"Verity enabled usr partition was requested but did not find a usr data partition.");
if (!m->partitions[PARTITION_USR_VERITY].found)
return log_debug_errno(
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
"Verity enabled usr partition was requested but did not find a usr verity hash partition");
"Verity enabled usr partition was requested but did not find a usr verity hash partition.");
m->partitions[PARTITION_USR].rw = false;
@@ -1619,7 +1601,7 @@ static int dissect_image(
if (m->partitions[di].found) {
found_flags = PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_UNUSED;
PartitionDesignator vi = partition_verity_of(di);
PartitionDesignator vi = partition_verity_hash_of(di);
if (vi >= 0 && m->partitions[vi].found) {
found_flags |= PARTITION_POLICY_VERITY;
@@ -1633,7 +1615,7 @@ static int dissect_image(
if (DEBUG_LOGGING) {
_cleanup_free_ char *s = NULL;
(void) partition_policy_flags_to_string(found_flags, /* simplify= */ false, &s);
log_debug("Found for designator %s: %s", partition_designator_to_string(di), strna(s));
log_debug("Found for designator %s: %s.", partition_designator_to_string(di), strna(s));
}
r = image_policy_check_protection(policy, di, found_flags);
@@ -3119,7 +3101,7 @@ int dissected_image_decrypt(
if (r < 0)
return r;
k = partition_verity_of(i);
k = partition_verity_hash_of(i);
if (k >= 0) {
flags |= getenv_bool("SYSTEMD_VERITY_SHARING") != 0 ? DISSECT_IMAGE_VERITY_SHARE : 0;
@@ -3608,7 +3590,7 @@ int dissected_image_load_verity_sig_partition(
if (!m->partitions[dd].found)
return 0;
PartitionDesignator dv = partition_verity_of(dd);
PartitionDesignator dv = partition_verity_hash_of(dd);
assert(dv >= 0);
if (!m->partitions[dv].found)
return 0;
@@ -3734,7 +3716,7 @@ int dissected_image_guess_verity_roothash(
if (!d->found)
return 0;
PartitionDesignator dv = partition_verity_of(dd);
PartitionDesignator dv = partition_verity_hash_of(dd);
assert(dv >= 0);
DissectedPartition *p = m->partitions + dv;
@@ -4178,7 +4160,7 @@ bool dissected_image_verity_candidate(const DissectedImage *image, PartitionDesi
if (image->single_file_system)
return partition_designator == PARTITION_ROOT && image->has_verity;
return partition_verity_of(partition_designator) >= 0;
return partition_verity_hash_of(partition_designator) >= 0;
}
bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignator partition_designator) {
@@ -4195,7 +4177,7 @@ bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignat
if (image->single_file_system)
return partition_designator == PARTITION_ROOT;
k = partition_verity_of(partition_designator);
k = partition_verity_hash_of(partition_designator);
return k >= 0 && image->partitions[k].found;
}

View File

@@ -31,7 +31,7 @@ bool partition_designator_is_versioned(PartitionDesignator d) {
PARTITION_USR_VERITY_SIG);
}
PartitionDesignator partition_verity_of(PartitionDesignator p) {
PartitionDesignator partition_verity_hash_of(PartitionDesignator p) {
switch (p) {
case PARTITION_ROOT:
@@ -59,7 +59,7 @@ PartitionDesignator partition_verity_sig_of(PartitionDesignator p) {
}
}
PartitionDesignator partition_verity_to_data(PartitionDesignator d) {
PartitionDesignator partition_verity_hash_to_data(PartitionDesignator d) {
switch (d) {
case PARTITION_ROOT_VERITY:
@@ -87,6 +87,14 @@ PartitionDesignator partition_verity_sig_to_data(PartitionDesignator d) {
}
}
PartitionDesignator partition_verity_to_data(PartitionDesignator d) {
PartitionDesignator e = partition_verity_hash_to_data(d);
if (e >= 0)
return e;
return partition_verity_sig_to_data(d);
}
static const char *const partition_designator_table[_PARTITION_DESIGNATOR_MAX] = {
[PARTITION_ROOT] = "root",
[PARTITION_USR] = "usr",

View File

@@ -31,19 +31,24 @@ typedef enum PartitionDesignator {
bool partition_designator_is_versioned(PartitionDesignator d) _const_;
PartitionDesignator partition_verity_of(PartitionDesignator p) _const_;
PartitionDesignator partition_verity_hash_of(PartitionDesignator p) _const_;
PartitionDesignator partition_verity_sig_of(PartitionDesignator p) _const_;
PartitionDesignator partition_verity_to_data(PartitionDesignator d) _const_;
PartitionDesignator partition_verity_hash_to_data(PartitionDesignator d) _const_;
PartitionDesignator partition_verity_sig_to_data(PartitionDesignator d) _const_;
PartitionDesignator partition_verity_to_data(PartitionDesignator d) _const_;
static inline bool partition_designator_is_verity(PartitionDesignator d) {
return partition_verity_to_data(d) >= 0;
static inline bool partition_designator_is_verity_hash(PartitionDesignator d) {
return partition_verity_hash_to_data(d) >= 0;
}
static inline bool partition_designator_is_verity_sig(PartitionDesignator d) {
return partition_verity_sig_to_data(d) >= 0;
}
static inline bool partition_designator_is_verity(PartitionDesignator d) {
return partition_verity_to_data(d) >= 0;
}
const char* partition_designator_to_string(PartitionDesignator d) _const_;
PartitionDesignator partition_designator_from_string(const char *name) _pure_;

View File

@@ -76,12 +76,12 @@ static PartitionPolicyFlags partition_policy_normalized_flags(const PartitionPol
/* If this is a verity or verity signature designator, then mask off all protection bits, this after
* all needs no protection, because it *is* the protection */
if (partition_verity_to_data(policy->designator) >= 0 ||
if (partition_verity_hash_to_data(policy->designator) >= 0 ||
partition_verity_sig_to_data(policy->designator) >= 0)
flags &= ~(PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED);
/* if this designator has no verity concept, then mask off verity protection flags */
if (partition_verity_of(policy->designator) < 0)
if (partition_verity_hash_of(policy->designator) < 0)
flags &= ~(PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED);
/* If the partition must be absent, then the gpt flags don't matter */
@@ -110,7 +110,7 @@ PartitionPolicyFlags image_policy_get(const ImagePolicy *policy, PartitionDesign
/* Hmm, so this didn't work, then let's see if we can derive some policy from the underlying data
* partition in case of verity/signature partitions */
data_designator = partition_verity_to_data(designator);
data_designator = partition_verity_hash_to_data(designator);
if (data_designator >= 0) {
PartitionPolicyFlags data_flags;

View File

@@ -48,17 +48,20 @@ TEST(verity_mappings) {
for (PartitionDesignator p = 0; p < _PARTITION_DESIGNATOR_MAX; p++) {
PartitionDesignator q;
q = partition_verity_of(p);
assert_se(q < 0 || partition_verity_to_data(q) == p);
q = partition_verity_hash_of(p);
assert_se(q < 0 || partition_verity_hash_to_data(q) == p);
q = partition_verity_sig_of(p);
assert_se(q < 0 || partition_verity_sig_to_data(q) == p);
q = partition_verity_to_data(p);
assert_se(q < 0 || partition_verity_of(q) == p);
q = partition_verity_hash_to_data(p);
assert_se(q < 0 || partition_verity_hash_of(q) == p);
q = partition_verity_sig_to_data(p);
assert_se(q < 0 || partition_verity_sig_of(q) == p);
q = partition_verity_to_data(p);
assert_se(q < 0 || partition_verity_hash_of(q) == p || partition_verity_sig_of(q) == p);
}
}

View File

@@ -265,7 +265,7 @@ static int verb_probe(UdevEvent *event, sd_device *dev) {
}
/* Indicate whether this partition has verity protection */
PartitionDesignator dv = partition_verity_of(d);
PartitionDesignator dv = partition_verity_hash_of(d);
if (dv >= 0 && image->partitions[dv].found) {
/* Add one property that indicates as a boolean whether Verity is available at all for this */
_cleanup_free_ char *f = NULL;