DissectedImage **ret) {
#if HAVE_BLKID
-#ifdef GPT_ROOT_NATIVE
sd_id128_t root_uuid = SD_ID128_NULL, root_verity_uuid = SD_ID128_NULL;
-#endif
-#ifdef GPT_USR_NATIVE
sd_id128_t usr_uuid = SD_ID128_NULL, usr_verity_uuid = SD_ID128_NULL;
-#endif
bool is_gpt, is_mbr, multiple_generic = false,
generic_rw = false, /* initialize to appease gcc */
generic_growfs = false;
/* If the verity data declares it's for the /usr partition, then search for that, in all
* other cases assume it's for the root partition. */
-#ifdef GPT_USR_NATIVE
if (verity->designator == PARTITION_USR) {
usr_uuid = fsuuid;
usr_verity_uuid = vuuid;
} else {
-#endif
-#ifdef GPT_ROOT_NATIVE
root_uuid = fsuuid;
root_verity_uuid = vuuid;
-#endif
-#ifdef GPT_USR_NATIVE
}
-#endif
}
if (fstat(fd, &st) < 0)
designator = PARTITION_XBOOTLDR;
rw = !(pflags & GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
- }
-#ifdef GPT_ROOT_NATIVE
- else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {
+
+ } else if (gpt_partition_type_is_root(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS);
if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
continue;
- designator = PARTITION_ROOT;
- architecture = native_architecture();
+ assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
+ designator = PARTITION_ROOT_OF_ARCH(architecture);
rw = !(pflags & GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
- } else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY)) {
+ } else if (gpt_partition_type_is_root_verity(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id))
continue;
- designator = PARTITION_ROOT_VERITY;
+ assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
+ designator = PARTITION_VERITY_OF(PARTITION_ROOT_OF_ARCH(architecture));
fstype = "DM_verity_hash";
- architecture = native_architecture();
rw = false;
- } else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY_SIG)) {
+ } else if (gpt_partition_type_is_root_verity_sig(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
if (verity->root_hash)
continue;
- designator = PARTITION_ROOT_VERITY_SIG;
+ assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
+ designator = PARTITION_VERITY_SIG_OF(PARTITION_ROOT_OF_ARCH(architecture));
fstype = "verity_hash_signature";
- architecture = native_architecture();
- rw = false;
- }
-#endif
-#ifdef GPT_ROOT_SECONDARY
- else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) {
-
- check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS);
-
- if (pflags & 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))
- continue;
-
- designator = PARTITION_ROOT_SECONDARY;
- architecture = SECONDARY_ARCHITECTURE;
- rw = !(pflags & GPT_FLAG_READ_ONLY);
- growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
-
- } else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY)) {
-
- check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
-
- if (pflags & GPT_FLAG_NO_AUTO)
- continue;
-
- m->has_verity = true;
-
- /* Don't do verity if no verity config is passed in */
- 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))
- continue;
-
- designator = PARTITION_ROOT_SECONDARY_VERITY;
- fstype = "DM_verity_hash";
- architecture = SECONDARY_ARCHITECTURE;
rw = false;
- } else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY_SIG)) {
-
- check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
-
- if (pflags & GPT_FLAG_NO_AUTO)
- continue;
-
- m->has_verity_sig = true;
-
- /* If root hash is specified explicitly, then ignore any embedded signature */
- if (!verity)
- continue;
- if (verity->designator >= 0 && verity->designator != PARTITION_ROOT)
- continue;
- if (verity->root_hash)
- continue;
-
- designator = PARTITION_ROOT_SECONDARY_VERITY_SIG;
- fstype = "verity_hash_signature";
- architecture = native_architecture();
- rw = false;
- }
-#endif
-#ifdef GPT_USR_NATIVE
- else if (sd_id128_equal(type_id, GPT_USR_NATIVE)) {
+ } else if (gpt_partition_type_is_usr(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS);
if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id))
continue;
- designator = PARTITION_USR;
- architecture = native_architecture();
+ assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
+ designator = PARTITION_USR_OF_ARCH(architecture);
rw = !(pflags & GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
- } else if (sd_id128_equal(type_id, GPT_USR_NATIVE_VERITY)) {
+ } else if (gpt_partition_type_is_usr_verity(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id))
continue;
- designator = PARTITION_USR_VERITY;
+ assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
+ designator = PARTITION_VERITY_OF(PARTITION_USR_OF_ARCH(architecture));
fstype = "DM_verity_hash";
- architecture = native_architecture();
rw = false;
- } else if (sd_id128_equal(type_id, GPT_USR_NATIVE_VERITY_SIG)) {
+ } else if (gpt_partition_type_is_usr_verity_sig(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
if (verity->root_hash)
continue;
- designator = PARTITION_USR_VERITY_SIG;
+ assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
+ designator = PARTITION_VERITY_SIG_OF(PARTITION_USR_OF_ARCH(architecture));
fstype = "verity_hash_signature";
- architecture = native_architecture();
- rw = false;
- }
-#endif
-#ifdef GPT_USR_SECONDARY
- else if (sd_id128_equal(type_id, GPT_USR_SECONDARY)) {
-
- check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS);
-
- if (pflags & 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))
- continue;
-
- designator = PARTITION_USR_SECONDARY;
- architecture = SECONDARY_ARCHITECTURE;
- rw = !(pflags & GPT_FLAG_READ_ONLY);
- growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
-
- } else if (sd_id128_equal(type_id, GPT_USR_SECONDARY_VERITY)) {
-
- check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
-
- if (pflags & 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 root id */
- if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id))
- continue;
-
- designator = PARTITION_USR_SECONDARY_VERITY;
- fstype = "DM_verity_hash";
- architecture = SECONDARY_ARCHITECTURE;
rw = false;
- } else if (sd_id128_equal(type_id, GPT_USR_SECONDARY_VERITY_SIG)) {
-
- check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
-
- if (pflags & GPT_FLAG_NO_AUTO)
- continue;
-
- m->has_verity_sig = true;
-
- /* If usr hash is specified explicitly, then ignore any embedded signature */
- if (!verity)
- continue;
- if (verity->designator >= 0 && verity->designator != PARTITION_USR)
- continue;
- if (verity->root_hash)
- continue;
-
- designator = PARTITION_USR_SECONDARY_VERITY_SIG;
- fstype = "verity_hash_signature";
- architecture = native_architecture();
- rw = false;
- }
-#endif
- else if (sd_id128_equal(type_id, GPT_SWAP)) {
+ } else if (sd_id128_equal(type_id, GPT_SWAP)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO);
}
if (m->partitions[PARTITION_ROOT].found) {
- /* If we found the primary arch, then invalidate the secondary arch to avoid any ambiguities,
- * since we never want to mount the secondary arch in this case. */
+ /* If we found the primary arch, then invalidate the secondary and other arch to avoid any
+ * ambiguities, since we never want to mount the secondary or other arch in this case. */
m->partitions[PARTITION_ROOT_SECONDARY].found = false;
m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false;
m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found = false;
m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false;
m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false;
+ m->partitions[PARTITION_ROOT_OTHER].found = false;
+ m->partitions[PARTITION_ROOT_OTHER_VERITY].found = false;
+ m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG].found = false;
+ m->partitions[PARTITION_USR_OTHER].found = false;
+ m->partitions[PARTITION_USR_OTHER_VERITY].found = false;
+ m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false;
+
} else if (m->partitions[PARTITION_ROOT_VERITY].found ||
m->partitions[PARTITION_ROOT_VERITY_SIG].found)
return -EADDRNOTAVAIL; /* Verity found but no matching rootfs? Something is off, refuse. */
else if (m->partitions[PARTITION_ROOT_SECONDARY].found) {
/* No root partition found but there's one for the secondary architecture? Then upgrade
- * secondary arch to first */
+ * secondary arch to first and invalidate the other arch. */
+
+ log_debug("No root partition found of the native architecture, falling back to a root "
+ "partition of the secondary architecture.");
m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY];
zero(m->partitions[PARTITION_ROOT_SECONDARY]);
m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG];
zero(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]);
+ m->partitions[PARTITION_ROOT_OTHER].found = false;
+ m->partitions[PARTITION_ROOT_OTHER_VERITY].found = false;
+ m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG].found = false;
+ m->partitions[PARTITION_USR_OTHER].found = false;
+ m->partitions[PARTITION_USR_OTHER_VERITY].found = false;
+ m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false;
+
} else if (m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found ||
m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found)
return -EADDRNOTAVAIL; /* as above */
+ else if (m->partitions[PARTITION_ROOT_OTHER].found) {
+
+ /* No root or secondary partition found but there's one for another architecture? Then
+ * upgrade the other architecture to first. */
+
+ log_debug("No root partition found of the native architecture or the secondary architecture, "
+ "falling back to a root partition of a non-native architecture (%s).",
+ architecture_to_string(m->partitions[PARTITION_ROOT_OTHER].architecture));
+
+ m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_OTHER];
+ zero(m->partitions[PARTITION_ROOT_OTHER]);
+ m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_OTHER_VERITY];
+ zero(m->partitions[PARTITION_ROOT_OTHER_VERITY]);
+ m->partitions[PARTITION_ROOT_VERITY_SIG] = m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG];
+ zero(m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG]);
+
+ m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_OTHER];
+ zero(m->partitions[PARTITION_USR_OTHER]);
+ m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_OTHER_VERITY];
+ zero(m->partitions[PARTITION_USR_OTHER_VERITY]);
+ m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_OTHER_VERITY_SIG];
+ zero(m->partitions[PARTITION_USR_OTHER_VERITY_SIG]);
+ }
+
/* 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 -EADDRNOTAVAIL;
if (m->partitions[PARTITION_USR].found) {
- /* Invalidate secondary arch /usr/ if we found the primary arch */
+ /* Invalidate secondary and other arch /usr/ if we found the primary arch */
m->partitions[PARTITION_USR_SECONDARY].found = false;
m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false;
m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false;
+ m->partitions[PARTITION_USR_OTHER].found = false;
+ m->partitions[PARTITION_USR_OTHER_VERITY].found = false;
+ m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false;
+
} else if (m->partitions[PARTITION_USR_VERITY].found ||
m->partitions[PARTITION_USR_VERITY_SIG].found)
return -EADDRNOTAVAIL; /* as above */
else if (m->partitions[PARTITION_USR_SECONDARY].found) {
+ log_debug("No usr partition found of the native architecture, falling back to a usr "
+ "partition of the secondary architecture.");
+
/* Upgrade secondary arch to primary */
m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_SECONDARY];
zero(m->partitions[PARTITION_USR_SECONDARY]);
m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG];
zero(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]);
+ m->partitions[PARTITION_USR_OTHER].found = false;
+ m->partitions[PARTITION_USR_OTHER_VERITY].found = false;
+ m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false;
+
} else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found ||
m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found)
return -EADDRNOTAVAIL; /* as above */
+ else if (m->partitions[PARTITION_USR_OTHER].found) {
+
+ log_debug("No usr partition found of the native architecture or the secondary architecture, "
+ "falling back to a usr partition of a non-native architecture (%s).",
+ architecture_to_string(m->partitions[PARTITION_ROOT_OTHER].architecture));
+
+ /* Upgrade other arch to primary */
+ m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_OTHER];
+ zero(m->partitions[PARTITION_USR_OTHER]);
+ m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_OTHER_VERITY];
+ zero(m->partitions[PARTITION_USR_OTHER_VERITY]);
+ m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_OTHER_VERITY_SIG];
+ zero(m->partitions[PARTITION_USR_OTHER_VERITY_SIG]);
+ }
+
/* Hmm, we found a signature partition but no Verity data? Something is off. */
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
return -EADDRNOTAVAIL;
(void) fs_grow(node, p);
if (remap_uid_gid) {
- r = remount_idmap(p, uid_shift, uid_range);
+ r = remount_idmap(p, uid_shift, uid_range, REMOUNT_IDMAP_HOST_ROOT);
if (r < 0)
return r;
}
_cleanup_(BIO_freep) BIO *bio = NULL; /* 'bio' must be freed first, 's' second, hence keep this order
* of declaration in place, please */
const unsigned char *d;
- char **i;
int r;
assert(verity);
}
const char* mount_options_from_designator(const MountOptions *options, PartitionDesignator designator) {
- const MountOptions *m;
-
LIST_FOREACH(mount_options, m, options)
if (designator == m->partition_designator && !isempty(m->options))
return m->options;
static const char *const partition_designator_table[] = {
[PARTITION_ROOT] = "root",
[PARTITION_ROOT_SECONDARY] = "root-secondary",
+ [PARTITION_ROOT_OTHER] = "root-other",
[PARTITION_USR] = "usr",
[PARTITION_USR_SECONDARY] = "usr-secondary",
+ [PARTITION_USR_OTHER] = "usr-other",
[PARTITION_HOME] = "home",
[PARTITION_SRV] = "srv",
[PARTITION_ESP] = "esp",
[PARTITION_SWAP] = "swap",
[PARTITION_ROOT_VERITY] = "root-verity",
[PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity",
+ [PARTITION_ROOT_OTHER_VERITY] = "root-other-verity",
[PARTITION_USR_VERITY] = "usr-verity",
[PARTITION_USR_SECONDARY_VERITY] = "usr-secondary-verity",
+ [PARTITION_USR_OTHER_VERITY] = "usr-other-verity",
[PARTITION_ROOT_VERITY_SIG] = "root-verity-sig",
[PARTITION_ROOT_SECONDARY_VERITY_SIG] = "root-secondary-verity-sig",
+ [PARTITION_ROOT_OTHER_VERITY_SIG] = "root-other-verity-sig",
[PARTITION_USR_VERITY_SIG] = "usr-verity-sig",
[PARTITION_USR_SECONDARY_VERITY_SIG] = "usr-secondary-verity-sig",
+ [PARTITION_USR_OTHER_VERITY_SIG] = "usr-other-verity-sig",
[PARTITION_TMP] = "tmp",
[PARTITION_VAR] = "var",
};
/* If we got os-release values from the caller, then we need to match them with the image's
* extension-release.d/ content. Return -EINVAL if there's any mismatch.
* First, check the distro ID. If that matches, then check the new SYSEXT_LEVEL value if
- * available, or else fallback to VERSION_ID. */
- if (required_host_os_release_id &&
- (required_host_os_release_version_id || required_host_os_release_sysext_level)) {
+ * available, or else fallback to VERSION_ID. If neither is present (eg: rolling release),
+ * then a simple match on the ID will be performed. */
+ if (required_host_os_release_id) {
_cleanup_strv_free_ char **extension_release = NULL;
r = load_extension_release_pairs(dest, dissected_image->image_name, &extension_release);