From c3c88d67c0ccd6fe883c79e0c5aa5c79379853ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Sep 2021 16:56:42 +0200 Subject: [PATCH 01/12] dissect-image: rename verity flag booleans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's make the booleans indicating verity state a bit more descriptive. Let's rename: can_verity → has_verity: because that's really what this about whether verity data is included in the image. Whether we actually can use it is a different story. verity → verity_ready: this one should tell us if we have everything need to actually set it up, hence explicitly say "ready to use" in the name. No change in behaviour. Just a bit of renaming. --- src/nspawn/nspawn.c | 2 +- src/shared/dissect-image.c | 30 ++++++++++++++++-------------- src/shared/dissect-image.h | 4 ++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 0966db4abe..ff2081d405 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5710,7 +5710,7 @@ static int run(int argc, char *argv[]) { if (r < 0) goto finish; - if (!arg_verity_settings.root_hash && dissected_image->can_verity) + if (!arg_verity_settings.root_hash && dissected_image->has_verity) log_notice("Note: image %s contains verity information, but no root hash specified! Proceeding without integrity checking.", arg_image); r = dissected_image_decrypt_interactively( diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 81ae0c3ffc..6b73c650e2 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -797,8 +797,12 @@ int dissect_image( return -ENOMEM; m->single_file_system = true; - m->verity = verity && verity->root_hash && verity->data_path && (verity->designator < 0 || verity->designator == PARTITION_ROOT); - m->can_verity = verity && verity->data_path; + m->encrypted = streq_ptr(fstype, "crypto_LUKS"); + + m->has_verity = verity && verity->data_path; + m->verity_ready = m->has_verity && + verity->root_hash && + (verity->designator < 0 || verity->designator == PARTITION_ROOT); options = mount_options_from_designator(mount_options, PARTITION_ROOT); if (options) { @@ -809,7 +813,7 @@ int dissect_image( m->partitions[PARTITION_ROOT] = (DissectedPartition) { .found = true, - .rw = !m->verity, + .rw = !m->verity_ready, .partno = -1, .architecture = _ARCHITECTURE_INVALID, .fstype = TAKE_PTR(t), @@ -817,8 +821,6 @@ int dissect_image( .mount_options = TAKE_PTR(o), }; - m->encrypted = streq_ptr(fstype, "crypto_LUKS"); - *ret = TAKE_PTR(m); return 0; } @@ -971,7 +973,7 @@ int dissect_image( if (pflags & GPT_FLAG_NO_AUTO) continue; - m->can_verity = true; + m->has_verity = true; /* Ignore verity unless a root hash is specified */ if (sd_id128_is_null(root_verity_uuid) || !sd_id128_equal(root_verity_uuid, id)) @@ -1007,7 +1009,7 @@ int dissect_image( if (pflags & GPT_FLAG_NO_AUTO) continue; - m->can_verity = true; + m->has_verity = true; /* Ignore verity unless root has is specified */ if (sd_id128_is_null(root_verity_uuid) || !sd_id128_equal(root_verity_uuid, id)) @@ -1043,7 +1045,7 @@ int dissect_image( if (pflags & GPT_FLAG_NO_AUTO) continue; - m->can_verity = true; + m->has_verity = true; /* Ignore verity unless a usr hash is specified */ if (sd_id128_is_null(usr_verity_uuid) || !sd_id128_equal(usr_verity_uuid, id)) @@ -1079,7 +1081,7 @@ int dissect_image( if (pflags & GPT_FLAG_NO_AUTO) continue; - m->can_verity = true; + m->has_verity = true; /* Ignore verity unless usr has is specified */ if (sd_id128_is_null(usr_verity_uuid) || !sd_id128_equal(usr_verity_uuid, id)) @@ -1386,7 +1388,7 @@ int dissect_image( /* If we found a verity setup, then the root partition is necessarily read-only. */ m->partitions[PARTITION_ROOT].rw = false; - m->verity = true; + m->verity_ready = true; } if (verity->designator == PARTITION_USR) { @@ -1394,7 +1396,7 @@ int dissect_image( return -EADDRNOTAVAIL; m->partitions[PARTITION_USR].rw = false; - m->verity = true; + m->verity_ready = true; } } @@ -2253,7 +2255,7 @@ int dissected_image_decrypt( if (verity && verity->root_hash && verity->root_hash_size < sizeof(sd_id128_t)) return -EINVAL; - if (!m->encrypted && !m->verity) { + if (!m->encrypted && !m->verity_ready) { *ret = NULL; return 0; } @@ -2840,7 +2842,7 @@ int dissect_image_and_warn( bool dissected_image_can_do_verity(const DissectedImage *image, PartitionDesignator partition_designator) { if (image->single_file_system) - return partition_designator == PARTITION_ROOT && image->can_verity; + return partition_designator == PARTITION_ROOT && image->has_verity; return PARTITION_VERITY_OF(partition_designator) >= 0; } @@ -2849,7 +2851,7 @@ bool dissected_image_has_verity(const DissectedImage *image, PartitionDesignator int k; if (image->single_file_system) - return partition_designator == PARTITION_ROOT && image->verity; + return partition_designator == PARTITION_ROOT && image->verity_ready; k = PARTITION_VERITY_OF(partition_designator); return k >= 0 && image->partitions[k].found; diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 4c4f5ff585..fe364474aa 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -118,8 +118,8 @@ typedef enum DissectImageFlags { struct DissectedImage { bool encrypted:1; - bool verity:1; /* verity available and usable */ - bool can_verity:1; /* verity available, but not necessarily used */ + bool has_verity:1; /* verity available in image, but not necessarily used */ + bool verity_ready:1; /* verity available, fully specified and usable */ bool single_file_system:1; /* MBR/GPT or single file system */ DissectedPartition partitions[_PARTITION_DESIGNATOR_MAX]; From 495367666b6742cdb8834f195b2578bf5029a33b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Sep 2021 17:26:32 +0200 Subject: [PATCH 02/12] dissect-image: rename dissected_image_has_verity()/_can_do_verity() Let's also pick more precise names for these helpers that are used for the tabular output: one checks whether a partition is candidate for verity at all, and the other checks if it is ready to be used for it. Let's make this clearer in the name. --- src/dissect/dissect.c | 4 ++-- src/shared/dissect-image.c | 25 +++++++++++++++++++++---- src/shared/dissect-image.h | 4 ++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index a42b138a80..3f464f8dad 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -514,8 +514,8 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) { if (arg_verity_settings.data_path) r = table_add_cell(t, NULL, TABLE_STRING, "external"); - else if (dissected_image_can_do_verity(m, i)) - r = table_add_cell(t, NULL, TABLE_STRING, yes_no(dissected_image_has_verity(m, i))); + else if (dissected_image_verity_candidate(m, i)) + r = table_add_cell(t, NULL, TABLE_STRING, yes_no(dissected_image_verity_ready(m, i))); else r = table_add_cell(t, NULL, TABLE_EMPTY, NULL); if (r < 0) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 6b73c650e2..20eade5a2a 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -2840,18 +2840,35 @@ int dissect_image_and_warn( } } -bool dissected_image_can_do_verity(const DissectedImage *image, PartitionDesignator partition_designator) { +bool dissected_image_verity_candidate(const DissectedImage *image, PartitionDesignator partition_designator) { + assert(image); + + /* Checks if this partition could theoretically do Verity. For non-partitioned images this only works + * if there's an external verity file supplied, for which we can consult .has_verity. For partitioned + * images we only check the partition type. + * + * This call is used to decide whether to suppress or show a verity column in tabular output of the + * image. */ + if (image->single_file_system) return partition_designator == PARTITION_ROOT && image->has_verity; return PARTITION_VERITY_OF(partition_designator) >= 0; } -bool dissected_image_has_verity(const DissectedImage *image, PartitionDesignator partition_designator) { - int k; +bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignator partition_designator) { + PartitionDesignator k; + + assert(image); + + /* Checks if this partition has verity data available that we can activate. For non-partitioned this + * works for the root partition, for others only if the associated verity partition was found. */ + + if (!image->verity_ready) + return false; if (image->single_file_system) - return partition_designator == PARTITION_ROOT && image->verity_ready; + return partition_designator == PARTITION_ROOT; k = PARTITION_VERITY_OF(partition_designator); return k >= 0 && image->partitions[k].found; diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index fe364474aa..55c8f29c28 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -186,8 +186,8 @@ PartitionDesignator partition_designator_from_string(const char *name) _pure_; int verity_settings_load(VeritySettings *verity, const char *image, const char *root_hash_path, const char *root_hash_sig_path); void verity_settings_done(VeritySettings *verity); -bool dissected_image_can_do_verity(const DissectedImage *image, PartitionDesignator d); -bool dissected_image_has_verity(const DissectedImage *image, PartitionDesignator d); +bool dissected_image_verity_candidate(const DissectedImage *image, PartitionDesignator d); +bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignator d); int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device, DecryptedImage **ret_decrypted_image); From a0bff7ea4c4b066b2498de893e3ebeda4638a0ce Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Sep 2021 17:28:37 +0200 Subject: [PATCH 03/12] dissect-image: tighten assertion checks on verity data --- src/shared/dissect-image.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 20eade5a2a..8d5c7e08e3 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -638,7 +638,10 @@ int dissect_image( assert(fd >= 0); assert(ret); + assert(!verity || verity->designator < 0 || IN_SET(verity->designator, PARTITION_ROOT, PARTITION_USR)); assert(!verity || verity->root_hash || verity->root_hash_size == 0); + assert(!verity || verity->root_hash_sig || verity->root_hash_sig_size == 0); + assert(!verity || (verity->root_hash || !verity->root_hash_sig)); assert(!((flags & DISSECT_IMAGE_GPT_ONLY) && (flags & DISSECT_IMAGE_NO_PARTITION_TABLE))); /* Probes a disk image, and returns information about what it found in *ret. From e0d53d529159c7c23b008028480d9f32adbf11d7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Sep 2021 17:29:06 +0200 Subject: [PATCH 04/12] dissect-image: also derive read-only mode from fstype in non-partitioned mode For the GPT partitioned logic we also consult the fstype to determine whether a partition is read-only (i.e. squashfs is already read-only). For the non-partitioned mode we didn't do that so far. Fix that. --- src/shared/dissect-image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 8d5c7e08e3..4f398316ae 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -816,7 +816,7 @@ int dissect_image( m->partitions[PARTITION_ROOT] = (DissectedPartition) { .found = true, - .rw = !m->verity_ready, + .rw = !m->verity_ready && !fstype_is_ro(fstype), .partno = -1, .architecture = _ARCHITECTURE_INVALID, .fstype = TAKE_PTR(t), From 0903fd268324fda1de615d621975aae27b53aa56 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Sep 2021 17:30:33 +0200 Subject: [PATCH 05/12] dissect-image: refuse external verity data in partitioned mode Our code doesn't support setting up verity with an external verity data file unless we operate in non-partitioned mode. Let's refuse this clearly and early if attempted anyway. --- src/shared/dissect-image.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 4f398316ae..480e4a2284 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -839,6 +839,10 @@ int dissect_image( if (!is_gpt && ((flags & DISSECT_IMAGE_GPT_ONLY) || !is_mbr)) return -ENOPKG; + /* We support external verity data partitions only if the image has no partition table */ + if (verity && verity->data_path) + return -EBADR; + /* Safety check: refuse block devices that carry a partition table but for which the kernel doesn't * do partition scanning. */ r = blockdev_partscan_enabled(fd); From 4ab51780c35ceb927c864c85b34cddb2f02cd72e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Sep 2021 11:12:23 +0200 Subject: [PATCH 06/12] dissect-image: mangle discovered /usr/ partition data, even if we found a root partition Previously, we'd clean up discovered /usr/ partition data only if we did not find a root partition. Given that we allow combinations of root and /usr partitions clean things up in both cases however. --- src/shared/dissect-image.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 480e4a2284..00ac8c6940 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1317,7 +1317,7 @@ int dissect_image( } else if (m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found) return -EADDRNOTAVAIL; /* as above */ - else if (m->partitions[PARTITION_USR].found) { + if (m->partitions[PARTITION_USR].found) { /* Invalidate secondary arch /usr/ if we found the primary arch */ m->partitions[PARTITION_USR_SECONDARY].found = false; @@ -1337,8 +1337,10 @@ int dissect_image( } else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found) return -EADDRNOTAVAIL; /* as above */ - else if ((flags & DISSECT_IMAGE_GENERIC_ROOT) && - (!verity || !verity->root_hash)) { + if (!m->partitions[PARTITION_ROOT].found && + !m->partitions[PARTITION_USR].found && + (flags & DISSECT_IMAGE_GENERIC_ROOT) && + (!verity || !verity->root_hash)) { /* OK, we found nothing usable, then check if there's a single generic one distro, and use * that. If the root hash was set however, then we won't fall back to a generic node, because From cb241a69e312cbd2c027b16aae76013b1a893dba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Sep 2021 11:24:44 +0200 Subject: [PATCH 07/12] dissect-image: insist that the architecture matches if both root and /usr partitions are found --- src/shared/dissect-image.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 00ac8c6940..566c073c29 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1337,6 +1337,14 @@ int dissect_image( } else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found) return -EADDRNOTAVAIL; /* as above */ + /* If root and /usr are combined then insist that the architecture matches */ + if (m->partitions[PARTITION_ROOT].found && + m->partitions[PARTITION_USR].found && + (m->partitions[PARTITION_ROOT].architecture >= 0 && + m->partitions[PARTITION_USR].architecture >= 0 && + m->partitions[PARTITION_ROOT].architecture != m->partitions[PARTITION_USR].architecture)) + return -EADDRNOTAVAIL; + if (!m->partitions[PARTITION_ROOT].found && !m->partitions[PARTITION_USR].found && (flags & DISSECT_IMAGE_GENERIC_ROOT) && From 00a8b34fa7220ecf7f5069f550bee53f9fc5ee47 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Sep 2021 11:18:47 +0200 Subject: [PATCH 08/12] dissect-image: don't do generic root partition fallback if verity is requested for /usr --- src/shared/dissect-image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 566c073c29..3279c843ec 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1348,7 +1348,7 @@ int dissect_image( if (!m->partitions[PARTITION_ROOT].found && !m->partitions[PARTITION_USR].found && (flags & DISSECT_IMAGE_GENERIC_ROOT) && - (!verity || !verity->root_hash)) { + (!verity || !verity->root_hash || verity->designator != PARTITION_USR)) { /* OK, we found nothing usable, then check if there's a single generic one distro, and use * that. If the root hash was set however, then we won't fall back to a generic node, because From ab5b2787fbd9100cac1b50a8e52707ba824d9756 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Sep 2021 11:29:19 +0200 Subject: [PATCH 09/12] dissect-image: drop redundant check We already check whether we discovered a /usr verity partition without a /usr partition when initially mangling the partitions, a bunch of lines further up, no need to repeat this here. --- src/shared/dissect-image.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 3279c843ec..8a139d4f8c 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1390,10 +1390,6 @@ int dissect_image( !(m->partitions[PARTITION_ROOT].found || (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT)))) return -ENXIO; - /* Refuse if we found a verity partition for /usr but no matching file system partition */ - if (!m->partitions[PARTITION_USR].found && m->partitions[PARTITION_USR_VERITY].found) - return -EADDRNOTAVAIL; - /* Combinations of verity /usr with verity-less root is OK, but the reverse is not */ if (m->partitions[PARTITION_ROOT_VERITY].found && m->partitions[PARTITION_USR].found && !m->partitions[PARTITION_USR_VERITY].found) return -EADDRNOTAVAIL; From 7b32164f3c666ff00027f7061e677482bf270a9e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Sep 2021 11:33:03 +0200 Subject: [PATCH 10/12] dissect-image: tighten checks on root + /usr/ combinations Our code logic doesn't support images with two verity partitions at the moment, hence refuse this early (with ENOTUNIQ) Also, go even further and refuse any combinations of verity enabled root with verity-less /usr, simplify because that is unsafe and defeats the point of verity. (i.e. we want to give the guarantee that for auto-discovered verity magic we guarantee that the data afterwards available in /usr is safe). --- src/shared/dissect-image.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 8a139d4f8c..9547dad808 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1390,9 +1390,16 @@ int dissect_image( !(m->partitions[PARTITION_ROOT].found || (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT)))) return -ENXIO; - /* Combinations of verity /usr with verity-less root is OK, but the reverse is not */ - if (m->partitions[PARTITION_ROOT_VERITY].found && m->partitions[PARTITION_USR].found && !m->partitions[PARTITION_USR_VERITY].found) - return -EADDRNOTAVAIL; + 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 -ENOTUNIQ; + + /* 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 -EADDRNOTAVAIL; + } if (verity && verity->root_hash) { if (verity->designator < 0 || verity->designator == PARTITION_ROOT) { From 1903defc2d1d0163d73f467f08b105ebb0619b40 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Sep 2021 11:38:52 +0200 Subject: [PATCH 11/12] dissect-image: insist that if a verity partition designator is specified the partition exists Let's tighten our checks further. --- src/shared/dissect-image.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 9547dad808..a540f86689 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1401,22 +1401,28 @@ int dissect_image( return -EADDRNOTAVAIL; } - if (verity && verity->root_hash) { - if (verity->designator < 0 || verity->designator == PARTITION_ROOT) { - if (!m->partitions[PARTITION_ROOT_VERITY].found || !m->partitions[PARTITION_ROOT].found) - return -EADDRNOTAVAIL; + if (verity) { + /* If a verity designator is specified, then insist that the matching partition exists */ + if (verity->designator >= 0 && !m->partitions[verity->designator].found) + return -EADDRNOTAVAIL; - /* If we found a verity setup, then the root partition is necessarily read-only. */ - m->partitions[PARTITION_ROOT].rw = false; - m->verity_ready = true; - } + if (verity->root_hash) { + if (verity->designator < 0 || verity->designator == PARTITION_ROOT) { + if (!m->partitions[PARTITION_ROOT_VERITY].found || !m->partitions[PARTITION_ROOT].found) + return -EADDRNOTAVAIL; - if (verity->designator == PARTITION_USR) { - if (!m->partitions[PARTITION_USR_VERITY].found || !m->partitions[PARTITION_USR].found) - return -EADDRNOTAVAIL; + /* If we found a verity setup, then the root partition is necessarily read-only. */ + m->partitions[PARTITION_ROOT].rw = false; + m->verity_ready = true; + } - m->partitions[PARTITION_USR].rw = false; - m->verity_ready = true; + if (verity->designator == PARTITION_USR) { + if (!m->partitions[PARTITION_USR_VERITY].found || !m->partitions[PARTITION_USR].found) + return -EADDRNOTAVAIL; + + m->partitions[PARTITION_USR].rw = false; + m->verity_ready = true; + } } } From f9e0bb6167766d3787d3b2c6722eb55a338ffe3c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Sep 2021 11:41:52 +0200 Subject: [PATCH 12/12] dissect-image: replace redundant if check by assert() We know that the designator can only be USR or ROOT (or negative), hence let's test that with an assert here, instead of doing an if check. --- src/shared/dissect-image.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index a540f86689..1cfbde683d 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1414,9 +1414,10 @@ int dissect_image( /* If we found a verity setup, then the root partition is necessarily read-only. */ m->partitions[PARTITION_ROOT].rw = false; m->verity_ready = true; - } - if (verity->designator == PARTITION_USR) { + } else { + assert(verity->designator == PARTITION_USR); + if (!m->partitions[PARTITION_USR_VERITY].found || !m->partitions[PARTITION_USR].found) return -EADDRNOTAVAIL;