dissect-image: process /usr/ GPT partition type
This commit is contained in:
parent
2bc181dae7
commit
aee36b4ea2
|
@ -942,7 +942,7 @@ static int mount_images(const MountEntry *m) {
|
||||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
||||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
||||||
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
|
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
|
||||||
_cleanup_(verity_settings_done) VeritySettings verity = {};
|
_cleanup_(verity_settings_done) VeritySettings verity = VERITY_SETTINGS_DEFAULT;
|
||||||
DissectImageFlags dissect_image_flags;
|
DissectImageFlags dissect_image_flags;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -1417,6 +1417,7 @@ static int verity_settings_prepare(
|
||||||
|
|
||||||
free_and_replace(verity->root_hash, d);
|
free_and_replace(verity->root_hash, d);
|
||||||
verity->root_hash_size = root_hash_size;
|
verity->root_hash_size = root_hash_size;
|
||||||
|
verity->designator = PARTITION_ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root_hash_sig) {
|
if (root_hash_sig) {
|
||||||
|
@ -1428,6 +1429,7 @@ static int verity_settings_prepare(
|
||||||
|
|
||||||
free_and_replace(verity->root_hash_sig, d);
|
free_and_replace(verity->root_hash_sig, d);
|
||||||
verity->root_hash_sig_size = root_hash_sig_size;
|
verity->root_hash_sig_size = root_hash_sig_size;
|
||||||
|
verity->designator = PARTITION_ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verity_data_path) {
|
if (verity_data_path) {
|
||||||
|
@ -1480,7 +1482,7 @@ int setup_namespace(
|
||||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
||||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
||||||
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
|
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
|
||||||
_cleanup_(verity_settings_done) VeritySettings verity = {};
|
_cleanup_(verity_settings_done) VeritySettings verity = VERITY_SETTINGS_DEFAULT;
|
||||||
MountEntry *m = NULL, *mounts = NULL;
|
MountEntry *m = NULL, *mounts = NULL;
|
||||||
bool require_prefix = false;
|
bool require_prefix = false;
|
||||||
const char *root;
|
const char *root;
|
||||||
|
|
|
@ -44,7 +44,7 @@ static const char *arg_path = NULL;
|
||||||
static const char *arg_source = NULL;
|
static const char *arg_source = NULL;
|
||||||
static const char *arg_target = NULL;
|
static const char *arg_target = NULL;
|
||||||
static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK;
|
static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK;
|
||||||
static VeritySettings arg_verity_settings = {};
|
static VeritySettings arg_verity_settings = VERITY_SETTINGS_DEFAULT;
|
||||||
static bool arg_json = false;
|
static bool arg_json = false;
|
||||||
static JsonFormatFlags arg_json_format_flags = 0;
|
static JsonFormatFlags arg_json_format_flags = 0;
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ static bool arg_notify_ready = false;
|
||||||
static bool arg_use_cgns = true;
|
static bool arg_use_cgns = true;
|
||||||
static unsigned long arg_clone_ns_flags = CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS;
|
static unsigned long arg_clone_ns_flags = CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS;
|
||||||
static MountSettingsMask arg_mount_settings = MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_TMPFS_TMP;
|
static MountSettingsMask arg_mount_settings = MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_TMPFS_TMP;
|
||||||
static VeritySettings arg_verity_settings = {};
|
static VeritySettings arg_verity_settings = VERITY_SETTINGS_DEFAULT;
|
||||||
static char **arg_syscall_allow_list = NULL;
|
static char **arg_syscall_allow_list = NULL;
|
||||||
static char **arg_syscall_deny_list = NULL;
|
static char **arg_syscall_deny_list = NULL;
|
||||||
#if HAVE_SECCOMP
|
#if HAVE_SECCOMP
|
||||||
|
|
|
@ -310,7 +310,8 @@ int dissect_image(
|
||||||
DissectedImage **ret) {
|
DissectedImage **ret) {
|
||||||
|
|
||||||
#if HAVE_BLKID
|
#if HAVE_BLKID
|
||||||
sd_id128_t root_uuid = SD_ID128_NULL, verity_uuid = SD_ID128_NULL;
|
sd_id128_t root_uuid = SD_ID128_NULL, root_verity_uuid = SD_ID128_NULL,
|
||||||
|
usr_uuid = SD_ID128_NULL, usr_verity_uuid = SD_ID128_NULL;
|
||||||
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||||
bool is_gpt, is_mbr, generic_rw, multiple_generic = false;
|
bool is_gpt, is_mbr, generic_rw, multiple_generic = false;
|
||||||
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
|
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
|
||||||
|
@ -335,20 +336,32 @@ int dissect_image(
|
||||||
* Returns -EADDRNOTAVAIL if a root hash was specified but no matching root/verity partitions found. */
|
* Returns -EADDRNOTAVAIL if a root hash was specified but no matching root/verity partitions found. */
|
||||||
|
|
||||||
if (verity && verity->root_hash) {
|
if (verity && verity->root_hash) {
|
||||||
/* If a root hash is supplied, then we use the root partition that has a UUID that match the first
|
sd_id128_t fsuuid, vuuid;
|
||||||
* 128bit of the root hash. And we use the verity partition that has a UUID that match the final
|
|
||||||
* 128bit. */
|
/* If a root hash is supplied, then we use the root partition that has a UUID that match the
|
||||||
|
* first 128bit of the root hash. And we use the verity partition that has a UUID that match
|
||||||
|
* the final 128bit. */
|
||||||
|
|
||||||
if (verity->root_hash_size < sizeof(sd_id128_t))
|
if (verity->root_hash_size < sizeof(sd_id128_t))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
memcpy(&root_uuid, verity->root_hash, sizeof(sd_id128_t));
|
memcpy(&fsuuid, verity->root_hash, sizeof(sd_id128_t));
|
||||||
memcpy(&verity_uuid, (const uint8_t*) verity->root_hash + verity->root_hash_size - sizeof(sd_id128_t), sizeof(sd_id128_t));
|
memcpy(&vuuid, (const uint8_t*) verity->root_hash + verity->root_hash_size - sizeof(sd_id128_t), sizeof(sd_id128_t));
|
||||||
|
|
||||||
if (sd_id128_is_null(root_uuid))
|
if (sd_id128_is_null(fsuuid))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (sd_id128_is_null(verity_uuid))
|
if (sd_id128_is_null(vuuid))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
if (verity->designator == PARTITION_USR) {
|
||||||
|
usr_uuid = fsuuid;
|
||||||
|
usr_verity_uuid = vuuid;
|
||||||
|
} else {
|
||||||
|
root_uuid = fsuuid;
|
||||||
|
root_verity_uuid = vuuid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(fd, &st) < 0)
|
if (fstat(fd, &st) < 0)
|
||||||
|
@ -395,6 +408,8 @@ int dissect_image(
|
||||||
(flags & DISSECT_IMAGE_NO_PARTITION_TABLE)) {
|
(flags & DISSECT_IMAGE_NO_PARTITION_TABLE)) {
|
||||||
const char *usage = NULL;
|
const char *usage = NULL;
|
||||||
|
|
||||||
|
/* If flags permit this, also allow using non-partitioned single-filesystem images */
|
||||||
|
|
||||||
(void) blkid_probe_lookup_value(b, "USAGE", &usage, NULL);
|
(void) blkid_probe_lookup_value(b, "USAGE", &usage, NULL);
|
||||||
if (STRPTR_IN_SET(usage, "filesystem", "crypto")) {
|
if (STRPTR_IN_SET(usage, "filesystem", "crypto")) {
|
||||||
_cleanup_free_ char *t = NULL, *n = NULL, *o = NULL;
|
_cleanup_free_ char *t = NULL, *n = NULL, *o = NULL;
|
||||||
|
@ -414,7 +429,7 @@ int dissect_image(
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
m->single_file_system = true;
|
m->single_file_system = true;
|
||||||
m->verity = verity && verity->root_hash && verity->data_path;
|
m->verity = verity && verity->root_hash && verity->data_path && (verity->designator < 0 || verity->designator == PARTITION_ROOT);
|
||||||
m->can_verity = verity && verity->data_path;
|
m->can_verity = verity && verity->data_path;
|
||||||
|
|
||||||
options = mount_options_from_designator(mount_options, PARTITION_ROOT);
|
options = mount_options_from_designator(mount_options, PARTITION_ROOT);
|
||||||
|
@ -528,6 +543,7 @@ int dissect_image(
|
||||||
|
|
||||||
designator = PARTITION_HOME;
|
designator = PARTITION_HOME;
|
||||||
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
} else if (sd_id128_equal(type_id, GPT_SRV)) {
|
} else if (sd_id128_equal(type_id, GPT_SRV)) {
|
||||||
|
|
||||||
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
||||||
|
@ -537,11 +553,13 @@ int dissect_image(
|
||||||
|
|
||||||
designator = PARTITION_SRV;
|
designator = PARTITION_SRV;
|
||||||
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
} else if (sd_id128_equal(type_id, GPT_ESP)) {
|
} else if (sd_id128_equal(type_id, GPT_ESP)) {
|
||||||
|
|
||||||
/* Note that we don't check the GPT_FLAG_NO_AUTO flag for the ESP, as it is not defined
|
/* Note that we don't check the GPT_FLAG_NO_AUTO flag for the ESP, as it is
|
||||||
* there. We instead check the GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as recommended by the
|
* not defined there. We instead check the GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as
|
||||||
* UEFI spec (See "12.3.3 Number and Location of System Partitions"). */
|
* recommended by the UEFI spec (See "12.3.3 Number and Location of System
|
||||||
|
* Partitions"). */
|
||||||
|
|
||||||
if (pflags & GPT_FLAG_NO_BLOCK_IO_PROTOCOL)
|
if (pflags & GPT_FLAG_NO_BLOCK_IO_PROTOCOL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -574,6 +592,7 @@ int dissect_image(
|
||||||
designator = PARTITION_ROOT;
|
designator = PARTITION_ROOT;
|
||||||
architecture = native_architecture();
|
architecture = native_architecture();
|
||||||
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
} else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY)) {
|
} else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY)) {
|
||||||
|
|
||||||
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
||||||
|
@ -584,7 +603,7 @@ int dissect_image(
|
||||||
m->can_verity = true;
|
m->can_verity = true;
|
||||||
|
|
||||||
/* Ignore verity unless a root hash is specified */
|
/* Ignore verity unless a root hash is specified */
|
||||||
if (sd_id128_is_null(verity_uuid) || !sd_id128_equal(verity_uuid, id))
|
if (sd_id128_is_null(root_verity_uuid) || !sd_id128_equal(root_verity_uuid, id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
designator = PARTITION_ROOT_VERITY;
|
designator = PARTITION_ROOT_VERITY;
|
||||||
|
@ -608,6 +627,7 @@ int dissect_image(
|
||||||
designator = PARTITION_ROOT_SECONDARY;
|
designator = PARTITION_ROOT_SECONDARY;
|
||||||
architecture = SECONDARY_ARCHITECTURE;
|
architecture = SECONDARY_ARCHITECTURE;
|
||||||
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
} else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY)) {
|
} else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY)) {
|
||||||
|
|
||||||
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
||||||
|
@ -618,7 +638,7 @@ int dissect_image(
|
||||||
m->can_verity = true;
|
m->can_verity = true;
|
||||||
|
|
||||||
/* Ignore verity unless root has is specified */
|
/* Ignore verity unless root has is specified */
|
||||||
if (sd_id128_is_null(verity_uuid) || !sd_id128_equal(verity_uuid, id))
|
if (sd_id128_is_null(root_verity_uuid) || !sd_id128_equal(root_verity_uuid, id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
designator = PARTITION_ROOT_SECONDARY_VERITY;
|
designator = PARTITION_ROOT_SECONDARY_VERITY;
|
||||||
|
@ -626,6 +646,76 @@ int dissect_image(
|
||||||
architecture = SECONDARY_ARCHITECTURE;
|
architecture = SECONDARY_ARCHITECTURE;
|
||||||
rw = false;
|
rw = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef GPT_USR_NATIVE
|
||||||
|
else if (sd_id128_equal(type_id, GPT_USR_NATIVE)) {
|
||||||
|
|
||||||
|
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
|
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;
|
||||||
|
architecture = native_architecture();
|
||||||
|
rw = !(pflags & GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
|
} else if (sd_id128_equal(type_id, GPT_USR_NATIVE_VERITY)) {
|
||||||
|
|
||||||
|
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
|
if (pflags & GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m->can_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))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
designator = PARTITION_USR_VERITY;
|
||||||
|
fstype = "DM_verity_hash";
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
} 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->can_verity = true;
|
||||||
|
|
||||||
|
/* Ignore verity unless usr has is specified */
|
||||||
|
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;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (sd_id128_equal(type_id, GPT_SWAP)) {
|
else if (sd_id128_equal(type_id, GPT_SWAP)) {
|
||||||
|
|
||||||
|
@ -636,6 +726,7 @@ int dissect_image(
|
||||||
|
|
||||||
designator = PARTITION_SWAP;
|
designator = PARTITION_SWAP;
|
||||||
fstype = "swap";
|
fstype = "swap";
|
||||||
|
|
||||||
} else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) {
|
} else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) {
|
||||||
|
|
||||||
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
|
||||||
|
@ -798,6 +889,8 @@ int dissect_image(
|
||||||
* since we never want to mount the secondary arch in this case. */
|
* since we never want to mount the secondary arch in this case. */
|
||||||
m->partitions[PARTITION_ROOT_SECONDARY].found = false;
|
m->partitions[PARTITION_ROOT_SECONDARY].found = false;
|
||||||
m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false;
|
m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false;
|
||||||
|
m->partitions[PARTITION_USR_SECONDARY].found = false;
|
||||||
|
m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false;
|
||||||
} else {
|
} else {
|
||||||
/* No root partition found? Then let's see if ther's one for the secondary architecture. And if not
|
/* No root partition found? Then let's see if ther's one for the secondary architecture. And if not
|
||||||
* either, then check if there's a single generic one, and use that. */
|
* either, then check if there's a single generic one, and use that. */
|
||||||
|
@ -805,13 +898,22 @@ int dissect_image(
|
||||||
if (m->partitions[PARTITION_ROOT_VERITY].found)
|
if (m->partitions[PARTITION_ROOT_VERITY].found)
|
||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
/* We didn't find a primary architecture root, but we found a primary architecture /usr? Refuse that for now. */
|
||||||
|
if (m->partitions[PARTITION_USR].found || m->partitions[PARTITION_USR_VERITY].found)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
if (m->partitions[PARTITION_ROOT_SECONDARY].found) {
|
if (m->partitions[PARTITION_ROOT_SECONDARY].found) {
|
||||||
|
/* Upgrade secondary arch to first */
|
||||||
m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY];
|
m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY];
|
||||||
zero(m->partitions[PARTITION_ROOT_SECONDARY]);
|
zero(m->partitions[PARTITION_ROOT_SECONDARY]);
|
||||||
|
|
||||||
m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_SECONDARY_VERITY];
|
m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_SECONDARY_VERITY];
|
||||||
zero(m->partitions[PARTITION_ROOT_SECONDARY_VERITY]);
|
zero(m->partitions[PARTITION_ROOT_SECONDARY_VERITY]);
|
||||||
|
|
||||||
|
m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_SECONDARY];
|
||||||
|
zero(m->partitions[PARTITION_USR_SECONDARY]);
|
||||||
|
m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_SECONDARY_VERITY];
|
||||||
|
zero(m->partitions[PARTITION_USR_SECONDARY_VERITY]);
|
||||||
|
|
||||||
} else if (flags & DISSECT_IMAGE_REQUIRE_ROOT) {
|
} else if (flags & DISSECT_IMAGE_REQUIRE_ROOT) {
|
||||||
_cleanup_free_ char *o = NULL;
|
_cleanup_free_ char *o = NULL;
|
||||||
const char *options = NULL;
|
const char *options = NULL;
|
||||||
|
@ -849,14 +951,31 @@ int dissect_image(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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_VERITY].found)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
if (verity && verity->root_hash) {
|
if (verity && verity->root_hash) {
|
||||||
if (!m->partitions[PARTITION_ROOT_VERITY].found || !m->partitions[PARTITION_ROOT].found)
|
if (verity->designator < 0 || verity->designator == PARTITION_ROOT) {
|
||||||
return -EADDRNOTAVAIL;
|
if (!m->partitions[PARTITION_ROOT_VERITY].found || !m->partitions[PARTITION_ROOT].found)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
/* If we found a verity setup, then the root partition is necessarily read-only. */
|
/* If we found a verity setup, then the root partition is necessarily read-only. */
|
||||||
m->partitions[PARTITION_ROOT].rw = false;
|
m->partitions[PARTITION_ROOT].rw = false;
|
||||||
|
m->verity = true;
|
||||||
|
}
|
||||||
|
|
||||||
m->verity = 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 = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blkid_free_probe(b);
|
blkid_free_probe(b);
|
||||||
|
@ -883,7 +1002,6 @@ int dissect_image(
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = TAKE_PTR(m);
|
*ret = TAKE_PTR(m);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
@ -1089,6 +1207,17 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift,
|
||||||
r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, uid_shift, flags);
|
r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, uid_shift, flags);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mask DISSECT_IMAGE_MKDIR for all subdirs: the idea is that only the top-level mount point is
|
||||||
|
* created if needed, but the image itself not modified. */
|
||||||
|
flags &= ~DISSECT_IMAGE_MKDIR;
|
||||||
|
|
||||||
|
if ((flags & DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY) == 0) {
|
||||||
|
/* For us mounting root always means mounting /usr as well */
|
||||||
|
r = mount_partition(m->partitions + PARTITION_USR, where, "/usr", uid_shift, flags);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
if (flags & DISSECT_IMAGE_VALIDATE_OS) {
|
if (flags & DISSECT_IMAGE_VALIDATE_OS) {
|
||||||
r = path_is_os_tree(where);
|
r = path_is_os_tree(where);
|
||||||
|
@ -1102,10 +1231,6 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift,
|
||||||
if (flags & DISSECT_IMAGE_MOUNT_ROOT_ONLY)
|
if (flags & DISSECT_IMAGE_MOUNT_ROOT_ONLY)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Mask DISSECT_IMAGE_MKDIR for all subdirs: the idea is that only the top-level mount point is
|
|
||||||
* created if needed, but the image itself not modified. */
|
|
||||||
flags &= ~DISSECT_IMAGE_MKDIR;
|
|
||||||
|
|
||||||
r = mount_partition(m->partitions + PARTITION_HOME, where, "/home", uid_shift, flags);
|
r = mount_partition(m->partitions + PARTITION_HOME, where, "/home", uid_shift, flags);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -1389,6 +1514,7 @@ static inline void dm_deferred_remove_clean(char *name) {
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char *, dm_deferred_remove_clean);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(char *, dm_deferred_remove_clean);
|
||||||
|
|
||||||
static int verity_partition(
|
static int verity_partition(
|
||||||
|
PartitionDesignator designator,
|
||||||
DissectedPartition *m,
|
DissectedPartition *m,
|
||||||
DissectedPartition *v,
|
DissectedPartition *v,
|
||||||
const VeritySettings *verity,
|
const VeritySettings *verity,
|
||||||
|
@ -1405,6 +1531,9 @@ static int verity_partition(
|
||||||
|
|
||||||
if (!verity || !verity->root_hash)
|
if (!verity || !verity->root_hash)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (!((verity->designator < 0 && designator == PARTITION_ROOT) ||
|
||||||
|
(verity->designator == designator)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!m->found || !m->node || !m->fstype)
|
if (!m->found || !m->node || !m->fstype)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1426,8 +1555,8 @@ static int verity_partition(
|
||||||
|
|
||||||
root_hash_encoded = hexmem(verity->root_hash, verity->root_hash_size);
|
root_hash_encoded = hexmem(verity->root_hash, verity->root_hash_size);
|
||||||
if (!root_hash_encoded)
|
if (!root_hash_encoded)
|
||||||
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
r = make_dm_name_and_node(root_hash_encoded, "-verity", &name, &node);
|
r = make_dm_name_and_node(root_hash_encoded, "-verity", &name, &node);
|
||||||
} else
|
} else
|
||||||
r = make_dm_name_and_node(m->node, "-verity", &name, &node);
|
r = make_dm_name_and_node(m->node, "-verity", &name, &node);
|
||||||
|
@ -1482,7 +1611,7 @@ static int verity_partition(
|
||||||
* Improvements in libcrypsetup can ensure this never happens:
|
* Improvements in libcrypsetup can ensure this never happens:
|
||||||
* https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/96 */
|
* https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/96 */
|
||||||
if (r == -EINVAL && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))
|
if (r == -EINVAL && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))
|
||||||
return verity_partition(m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d);
|
return verity_partition(designator, m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d);
|
||||||
if (!IN_SET(r,
|
if (!IN_SET(r,
|
||||||
0, /* Success */
|
0, /* Success */
|
||||||
-EEXIST, /* Volume is already open and ready to be used */
|
-EEXIST, /* Volume is already open and ready to be used */
|
||||||
|
@ -1508,7 +1637,7 @@ static int verity_partition(
|
||||||
r = verity_can_reuse(verity, name, &existing_cd);
|
r = verity_can_reuse(verity, name, &existing_cd);
|
||||||
/* Same as above, -EINVAL can randomly happen when it actually means -EEXIST */
|
/* Same as above, -EINVAL can randomly happen when it actually means -EEXIST */
|
||||||
if (r == -EINVAL && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))
|
if (r == -EINVAL && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))
|
||||||
return verity_partition(m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d);
|
return verity_partition(designator, m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d);
|
||||||
if (!IN_SET(r, 0, -ENODEV, -ENOENT, -EBUSY))
|
if (!IN_SET(r, 0, -ENODEV, -ENOENT, -EBUSY))
|
||||||
return log_debug_errno(r, "Checking whether existing verity device %s can be reused failed: %m", node);
|
return log_debug_errno(r, "Checking whether existing verity device %s can be reused failed: %m", node);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
|
@ -1536,7 +1665,7 @@ static int verity_partition(
|
||||||
/* An existing verity device was reported by libcryptsetup/libdevmapper, but we can't use it at this time.
|
/* An existing verity device was reported by libcryptsetup/libdevmapper, but we can't use it at this time.
|
||||||
* Fall back to activating it with a unique device name. */
|
* Fall back to activating it with a unique device name. */
|
||||||
if (r != 0 && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))
|
if (r != 0 && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))
|
||||||
return verity_partition(m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d);
|
return verity_partition(designator, m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d);
|
||||||
|
|
||||||
/* Everything looks good and we'll be able to mount the device, so deferred remove will be re-enabled at that point. */
|
/* Everything looks good and we'll be able to mount the device, so deferred remove will be re-enabled at that point. */
|
||||||
restore_deferred_remove = mfree(restore_deferred_remove);
|
restore_deferred_remove = mfree(restore_deferred_remove);
|
||||||
|
@ -1601,7 +1730,7 @@ int dissected_image_decrypt(
|
||||||
|
|
||||||
k = PARTITION_VERITY_OF(i);
|
k = PARTITION_VERITY_OF(i);
|
||||||
if (k >= 0) {
|
if (k >= 0) {
|
||||||
r = verity_partition(p, m->partitions + k, verity, flags | DISSECT_IMAGE_VERITY_SHARE, d);
|
r = verity_partition(i, p, m->partitions + k, verity, flags | DISSECT_IMAGE_VERITY_SHARE, d);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1727,39 +1856,84 @@ int verity_settings_load(
|
||||||
_cleanup_free_ void *root_hash = NULL, *root_hash_sig = NULL;
|
_cleanup_free_ void *root_hash = NULL, *root_hash_sig = NULL;
|
||||||
size_t root_hash_size = 0, root_hash_sig_size = 0;
|
size_t root_hash_size = 0, root_hash_sig_size = 0;
|
||||||
_cleanup_free_ char *verity_data_path = NULL;
|
_cleanup_free_ char *verity_data_path = NULL;
|
||||||
|
PartitionDesignator designator;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(verity);
|
assert(verity);
|
||||||
assert(image);
|
assert(image);
|
||||||
|
assert(verity->designator < 0 || IN_SET(verity->designator, PARTITION_ROOT, PARTITION_USR));
|
||||||
|
|
||||||
/* If we are asked to load the root hash for a device node, exit early */
|
/* If we are asked to load the root hash for a device node, exit early */
|
||||||
if (is_device_path(image))
|
if (is_device_path(image))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
designator = verity->designator;
|
||||||
|
|
||||||
/* We only fill in what isn't already filled in */
|
/* We only fill in what isn't already filled in */
|
||||||
|
|
||||||
if (!verity->root_hash) {
|
if (!verity->root_hash) {
|
||||||
_cleanup_free_ char *text = NULL;
|
_cleanup_free_ char *text = NULL;
|
||||||
|
|
||||||
if (root_hash_path) {
|
if (root_hash_path) {
|
||||||
|
/* If explicitly specified it takes precedence */
|
||||||
r = read_one_line_file(root_hash_path, &text);
|
r = read_one_line_file(root_hash_path, &text);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (designator < 0)
|
||||||
|
designator = PARTITION_ROOT;
|
||||||
} else {
|
} else {
|
||||||
r = getxattr_malloc(image, "user.verity.roothash", &text, true);
|
/* Otherwise look for xattr and separate file, and first for the data for root and if
|
||||||
if (r < 0) {
|
* that doesn't exist for /usr */
|
||||||
_cleanup_free_ char *p = NULL;
|
|
||||||
|
|
||||||
if (!IN_SET(r, -ENODATA, -ENOENT) && !ERRNO_IS_NOT_SUPPORTED(r))
|
if (designator < 0 || designator == PARTITION_ROOT) {
|
||||||
return r;
|
r = getxattr_malloc(image, "user.verity.roothash", &text, true);
|
||||||
|
if (r < 0) {
|
||||||
|
_cleanup_free_ char *p = NULL;
|
||||||
|
|
||||||
p = build_auxiliary_path(image, ".roothash");
|
if (!IN_SET(r, -ENODATA, -ENOENT) && !ERRNO_IS_NOT_SUPPORTED(r))
|
||||||
if (!p)
|
return r;
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
r = read_one_line_file(p, &text);
|
p = build_auxiliary_path(image, ".roothash");
|
||||||
if (r < 0 && r != -ENOENT)
|
if (!p)
|
||||||
return r;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = read_one_line_file(p, &text);
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text)
|
||||||
|
designator = PARTITION_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!text && (designator < 0 || designator == PARTITION_USR)) {
|
||||||
|
/* So in the "roothash" xattr/file name above the "root" of course primarily
|
||||||
|
* refers to the root of the Verity Merkle tree. But coincidentally it also
|
||||||
|
* is the hash for the *root* file system, i.e. the "root" neatly refers to
|
||||||
|
* two distinct concepts called "root". Taking benefit of this happy
|
||||||
|
* coincidence we call the file with the root hash for the /usr/ file system
|
||||||
|
* `usrhash`, because `usrroothash` or `rootusrhash` would just be too
|
||||||
|
* confusing. We thus drop the reference to the root of the Merkle tree, and
|
||||||
|
* just indicate which file system it's about. */
|
||||||
|
r = getxattr_malloc(image, "user.verity.usrhash", &text, true);
|
||||||
|
if (r < 0) {
|
||||||
|
_cleanup_free_ char *p = NULL;
|
||||||
|
|
||||||
|
if (!IN_SET(r, -ENODATA, -ENOENT) && !ERRNO_IS_NOT_SUPPORTED(r))
|
||||||
|
return r;
|
||||||
|
|
||||||
|
p = build_auxiliary_path(image, ".usrhash");
|
||||||
|
if (!p)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = read_one_line_file(p, &text);
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text)
|
||||||
|
designator = PARTITION_USR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1772,24 +1946,47 @@ int verity_settings_load(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!verity->root_hash_sig) {
|
if (verity->root_hash && !verity->root_hash_sig) {
|
||||||
_cleanup_free_ char *p = NULL;
|
if (root_hash_sig_path) {
|
||||||
|
r = read_full_file_full(AT_FDCWD, root_hash_sig_path, 0, (char**) &root_hash_sig, &root_hash_sig_size);
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
return r;
|
||||||
|
|
||||||
if (!root_hash_sig_path) {
|
if (designator < 0)
|
||||||
/* Follow naming convention recommended by the relevant RFC:
|
designator = PARTITION_ROOT;
|
||||||
* https://tools.ietf.org/html/rfc5751#section-3.2.1 */
|
} else {
|
||||||
p = build_auxiliary_path(image, ".roothash.p7s");
|
if (designator < 0 || designator == PARTITION_ROOT) {
|
||||||
if (!p)
|
_cleanup_free_ char *p = NULL;
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
root_hash_sig_path = p;
|
/* Follow naming convention recommended by the relevant RFC:
|
||||||
|
* https://tools.ietf.org/html/rfc5751#section-3.2.1 */
|
||||||
|
p = build_auxiliary_path(image, ".roothash.p7s");
|
||||||
|
if (!p)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = read_full_file_full(AT_FDCWD, root_hash_sig_path, 0, (char**) &root_hash_sig, &root_hash_sig_size);
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
return r;
|
||||||
|
if (r >= 0)
|
||||||
|
designator = PARTITION_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!root_hash_sig && (designator < 0 || designator == PARTITION_USR)) {
|
||||||
|
_cleanup_free_ char *p = NULL;
|
||||||
|
|
||||||
|
p = build_auxiliary_path(image, ".usrhash.p7s");
|
||||||
|
if (!p)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = read_full_file_full(AT_FDCWD, root_hash_sig_path, 0, (char**) &root_hash_sig, &root_hash_sig_size);
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
return r;
|
||||||
|
if (r >= 0)
|
||||||
|
designator = PARTITION_USR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = read_full_file_full(AT_FDCWD, root_hash_sig_path, 0, (char**) &root_hash_sig, &root_hash_sig_size);
|
if (root_hash_sig && root_hash_sig_size == 0) /* refuse empty size signatures */
|
||||||
if (r < 0) {
|
|
||||||
if (r != -ENOENT)
|
|
||||||
return r;
|
|
||||||
} else if (root_hash_sig_size == 0) /* refuse empty size signatures */
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1820,6 +2017,9 @@ int verity_settings_load(
|
||||||
if (verity_data_path)
|
if (verity_data_path)
|
||||||
verity->data_path = TAKE_PTR(verity_data_path);
|
verity->data_path = TAKE_PTR(verity_data_path);
|
||||||
|
|
||||||
|
if (verity->designator < 0)
|
||||||
|
verity->designator = designator;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2018,7 +2218,6 @@ int dissect_image_and_warn(
|
||||||
}
|
}
|
||||||
|
|
||||||
r = dissect_image(fd, verity, mount_options, flags, ret);
|
r = dissect_image(fd, verity, mount_options, flags, ret);
|
||||||
|
|
||||||
switch (r) {
|
switch (r) {
|
||||||
|
|
||||||
case -EOPNOTSUPP:
|
case -EOPNOTSUPP:
|
||||||
|
@ -2161,6 +2360,8 @@ int mount_image_privately_interactively(
|
||||||
static const char *const partition_designator_table[] = {
|
static const char *const partition_designator_table[] = {
|
||||||
[PARTITION_ROOT] = "root",
|
[PARTITION_ROOT] = "root",
|
||||||
[PARTITION_ROOT_SECONDARY] = "root-secondary",
|
[PARTITION_ROOT_SECONDARY] = "root-secondary",
|
||||||
|
[PARTITION_USR] = "usr",
|
||||||
|
[PARTITION_USR_SECONDARY] = "usr-secondary",
|
||||||
[PARTITION_HOME] = "home",
|
[PARTITION_HOME] = "home",
|
||||||
[PARTITION_SRV] = "srv",
|
[PARTITION_SRV] = "srv",
|
||||||
[PARTITION_ESP] = "esp",
|
[PARTITION_ESP] = "esp",
|
||||||
|
@ -2168,6 +2369,8 @@ static const char *const partition_designator_table[] = {
|
||||||
[PARTITION_SWAP] = "swap",
|
[PARTITION_SWAP] = "swap",
|
||||||
[PARTITION_ROOT_VERITY] = "root-verity",
|
[PARTITION_ROOT_VERITY] = "root-verity",
|
||||||
[PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity",
|
[PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity",
|
||||||
|
[PARTITION_USR_VERITY] = "usr-verity",
|
||||||
|
[PARTITION_USR_SECONDARY_VERITY] = "usr-secondary-verity",
|
||||||
[PARTITION_TMP] = "tmp",
|
[PARTITION_TMP] = "tmp",
|
||||||
[PARTITION_VAR] = "var",
|
[PARTITION_VAR] = "var",
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,8 @@ struct DissectedPartition {
|
||||||
typedef enum PartitionDesignator {
|
typedef enum PartitionDesignator {
|
||||||
PARTITION_ROOT,
|
PARTITION_ROOT,
|
||||||
PARTITION_ROOT_SECONDARY, /* Secondary architecture */
|
PARTITION_ROOT_SECONDARY, /* Secondary architecture */
|
||||||
|
PARTITION_USR,
|
||||||
|
PARTITION_USR_SECONDARY,
|
||||||
PARTITION_HOME,
|
PARTITION_HOME,
|
||||||
PARTITION_SRV,
|
PARTITION_SRV,
|
||||||
PARTITION_ESP,
|
PARTITION_ESP,
|
||||||
|
@ -38,6 +40,8 @@ typedef enum PartitionDesignator {
|
||||||
PARTITION_SWAP,
|
PARTITION_SWAP,
|
||||||
PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */
|
PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */
|
||||||
PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */
|
PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */
|
||||||
|
PARTITION_USR_VERITY,
|
||||||
|
PARTITION_USR_SECONDARY_VERITY,
|
||||||
PARTITION_TMP,
|
PARTITION_TMP,
|
||||||
PARTITION_VAR,
|
PARTITION_VAR,
|
||||||
_PARTITION_DESIGNATOR_MAX,
|
_PARTITION_DESIGNATOR_MAX,
|
||||||
|
@ -45,11 +49,23 @@ typedef enum PartitionDesignator {
|
||||||
} PartitionDesignator;
|
} PartitionDesignator;
|
||||||
|
|
||||||
static inline PartitionDesignator PARTITION_VERITY_OF(PartitionDesignator p) {
|
static inline PartitionDesignator PARTITION_VERITY_OF(PartitionDesignator p) {
|
||||||
if (p == PARTITION_ROOT)
|
switch (p) {
|
||||||
|
|
||||||
|
case PARTITION_ROOT:
|
||||||
return PARTITION_ROOT_VERITY;
|
return PARTITION_ROOT_VERITY;
|
||||||
if (p == PARTITION_ROOT_SECONDARY)
|
|
||||||
|
case PARTITION_ROOT_SECONDARY:
|
||||||
return PARTITION_ROOT_SECONDARY_VERITY;
|
return PARTITION_ROOT_SECONDARY_VERITY;
|
||||||
return _PARTITION_DESIGNATOR_INVALID;
|
|
||||||
|
case PARTITION_USR:
|
||||||
|
return PARTITION_USR_VERITY;
|
||||||
|
|
||||||
|
case PARTITION_USR_SECONDARY:
|
||||||
|
return PARTITION_USR_SECONDARY_VERITY;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return _PARTITION_DESIGNATOR_INVALID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum DissectImageFlags {
|
typedef enum DissectImageFlags {
|
||||||
|
@ -61,9 +77,9 @@ typedef enum DissectImageFlags {
|
||||||
DISSECT_IMAGE_DISCARD |
|
DISSECT_IMAGE_DISCARD |
|
||||||
DISSECT_IMAGE_DISCARD_ON_CRYPTO,
|
DISSECT_IMAGE_DISCARD_ON_CRYPTO,
|
||||||
DISSECT_IMAGE_GPT_ONLY = 1 << 4, /* Only recognize images with GPT partition tables */
|
DISSECT_IMAGE_GPT_ONLY = 1 << 4, /* Only recognize images with GPT partition tables */
|
||||||
DISSECT_IMAGE_REQUIRE_ROOT = 1 << 5, /* Don't accept disks without root partition */
|
DISSECT_IMAGE_REQUIRE_ROOT = 1 << 5, /* Don't accept disks without root partition (and if no partition table or only single generic partition, assume it's root) */
|
||||||
DISSECT_IMAGE_MOUNT_ROOT_ONLY = 1 << 6, /* Mount only the root partition */
|
DISSECT_IMAGE_MOUNT_ROOT_ONLY = 1 << 6, /* Mount only the root and /usr partitions */
|
||||||
DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY = 1 << 7, /* Mount only non-root partitions */
|
DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY = 1 << 7, /* Mount only the non-root and non-/usr partitions */
|
||||||
DISSECT_IMAGE_VALIDATE_OS = 1 << 8, /* Refuse mounting images that aren't identifiable as OS images */
|
DISSECT_IMAGE_VALIDATE_OS = 1 << 8, /* Refuse mounting images that aren't identifiable as OS images */
|
||||||
DISSECT_IMAGE_NO_UDEV = 1 << 9, /* Don't wait for udev initializing things */
|
DISSECT_IMAGE_NO_UDEV = 1 << 9, /* Don't wait for udev initializing things */
|
||||||
DISSECT_IMAGE_RELAX_VAR_CHECK = 1 << 10, /* Don't insist that the UUID of /var is hashed from /etc/machine-id */
|
DISSECT_IMAGE_RELAX_VAR_CHECK = 1 << 10, /* Don't insist that the UUID of /var is hashed from /etc/machine-id */
|
||||||
|
@ -104,8 +120,15 @@ struct VeritySettings {
|
||||||
|
|
||||||
/* Path to the verity data file, if stored externally */
|
/* Path to the verity data file, if stored externally */
|
||||||
char *data_path;
|
char *data_path;
|
||||||
|
|
||||||
|
/* PARTITION_ROOT or PARTITION_USR, depending on what these Verity settings are for */
|
||||||
|
PartitionDesignator designator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define VERITY_SETTINGS_DEFAULT { \
|
||||||
|
.designator = _PARTITION_DESIGNATOR_INVALID \
|
||||||
|
}
|
||||||
|
|
||||||
MountOptions* mount_options_free_all(MountOptions *options);
|
MountOptions* mount_options_free_all(MountOptions *options);
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(MountOptions*, mount_options_free_all);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(MountOptions*, mount_options_free_all);
|
||||||
const char* mount_options_from_designator(const MountOptions *options, PartitionDesignator designator);
|
const char* mount_options_from_designator(const MountOptions *options, PartitionDesignator designator);
|
||||||
|
|
Loading…
Reference in New Issue