From d29a2cd2d4f2712475e87ce2a0941ec79ddd1c37 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 14 Oct 2025 20:14:39 +0100 Subject: [PATCH 1/4] mountfsd: json format unsigned types as unsigned sizes/offsets are unsigned ints, so use the appropriate macros to build the json messages, otherwise UINT64T_MAX is sent as -1 --- src/mountfsd/mountwork.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mountfsd/mountwork.c b/src/mountfsd/mountwork.c index 74b97d7371..77d93025b0 100644 --- a/src/mountfsd/mountwork.c +++ b/src/mountfsd/mountwork.c @@ -561,8 +561,8 @@ static int vl_method_mount_image( SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(pp->uuid), "partitionUuid", SD_JSON_BUILD_UUID(pp->uuid)), SD_JSON_BUILD_PAIR("fileSystemType", SD_JSON_BUILD_STRING(dissected_partition_fstype(pp))), SD_JSON_BUILD_PAIR_CONDITION(!!pp->label, "partitionLabel", SD_JSON_BUILD_STRING(pp->label)), - SD_JSON_BUILD_PAIR("size", SD_JSON_BUILD_INTEGER(pp->size)), - SD_JSON_BUILD_PAIR("offset", SD_JSON_BUILD_INTEGER(pp->offset)), + SD_JSON_BUILD_PAIR("size", SD_JSON_BUILD_UNSIGNED(pp->size)), + SD_JSON_BUILD_PAIR("offset", SD_JSON_BUILD_UNSIGNED(pp->offset)), SD_JSON_BUILD_PAIR("mountFileDescriptor", SD_JSON_BUILD_INTEGER(fd_idx)), JSON_BUILD_PAIR_STRV_NON_EMPTY("mountPoint", l)); if (r < 0) @@ -575,8 +575,8 @@ static int vl_method_mount_image( link, SD_JSON_BUILD_PAIR("partitions", SD_JSON_BUILD_VARIANT(aj)), SD_JSON_BUILD_PAIR("imagePolicy", SD_JSON_BUILD_STRING(ps)), - SD_JSON_BUILD_PAIR("imageSize", SD_JSON_BUILD_INTEGER(di->image_size)), - SD_JSON_BUILD_PAIR("sectorSize", SD_JSON_BUILD_INTEGER(di->sector_size)), + SD_JSON_BUILD_PAIR("imageSize", SD_JSON_BUILD_UNSIGNED(di->image_size)), + SD_JSON_BUILD_PAIR("sectorSize", SD_JSON_BUILD_UNSIGNED(di->sector_size)), SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(di->image_uuid), "imageUuid", SD_JSON_BUILD_UUID(di->image_uuid))); } From a9b1e35a32a9377e9741124704229e4875c1f55b Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 14 Oct 2025 18:37:30 +0100 Subject: [PATCH 2/4] mountfsd: add boolean parameter to let callers enable verity sharing --- src/mountfsd/mountwork.c | 15 +++++++++------ src/shared/varlink-io.systemd.MountFileSystem.c | 2 ++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/mountfsd/mountwork.c b/src/mountfsd/mountwork.c index 77d93025b0..fe0791aacf 100644 --- a/src/mountfsd/mountwork.c +++ b/src/mountfsd/mountwork.c @@ -89,6 +89,7 @@ typedef struct MountImageParameters { int growfs; char *password; ImagePolicy *image_policy; + bool verity_sharing; } MountImageParameters; static void mount_image_parameters_done(MountImageParameters *p) { @@ -283,12 +284,13 @@ static int vl_method_mount_image( void *userdata) { static const sd_json_dispatch_field dispatch_table[] = { - { "imageFileDescriptor", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(MountImageParameters, image_fd_idx), SD_JSON_MANDATORY }, - { "userNamespaceFileDescriptor", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(MountImageParameters, userns_fd_idx), 0 }, - { "readOnly", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MountImageParameters, read_only), 0 }, - { "growFileSystems", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MountImageParameters, growfs), 0 }, - { "password", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MountImageParameters, password), 0 }, - { "imagePolicy", SD_JSON_VARIANT_STRING, json_dispatch_image_policy, offsetof(MountImageParameters, image_policy), 0 }, + { "imageFileDescriptor", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(MountImageParameters, image_fd_idx), SD_JSON_MANDATORY }, + { "userNamespaceFileDescriptor", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(MountImageParameters, userns_fd_idx), 0 }, + { "readOnly", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MountImageParameters, read_only), 0 }, + { "growFileSystems", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MountImageParameters, growfs), 0 }, + { "password", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MountImageParameters, password), 0 }, + { "imagePolicy", SD_JSON_VARIANT_STRING, json_dispatch_image_policy, offsetof(MountImageParameters, image_policy), 0 }, + { "veritySharing", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(MountImageParameters, verity_sharing), 0 }, VARLINK_DISPATCH_POLKIT_FIELD, {} }; @@ -403,6 +405,7 @@ static int vl_method_mount_image( DISSECT_IMAGE_FSCK | DISSECT_IMAGE_ADD_PARTITION_DEVICES | DISSECT_IMAGE_PIN_PARTITION_DEVICES | + (p.verity_sharing ? DISSECT_IMAGE_VERITY_SHARE : 0) | DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; /* Let's see if we have acquired the privilege to mount untrusted images already */ diff --git a/src/shared/varlink-io.systemd.MountFileSystem.c b/src/shared/varlink-io.systemd.MountFileSystem.c index 80c4473163..ce54cf3839 100644 --- a/src/shared/varlink-io.systemd.MountFileSystem.c +++ b/src/shared/varlink-io.systemd.MountFileSystem.c @@ -60,6 +60,8 @@ static SD_VARLINK_DEFINE_METHOD( SD_VARLINK_DEFINE_INPUT(password, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("Takes an image policy string (see systemd.image-policy(7) for details) to apply while mounting the image"), SD_VARLINK_DEFINE_INPUT(imagePolicy, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Whether to automatically reuse already set up dm-verity devices that share the same roothash."), + SD_VARLINK_DEFINE_INPUT(veritySharing, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), VARLINK_DEFINE_POLKIT_INPUT, SD_VARLINK_FIELD_COMMENT("An array with information about contained partitions that have been prepared for mounting, as well as their mount file descriptors."), SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(partitions, PartitionInfo, SD_VARLINK_ARRAY), From ce7a5d60269c2303b7d59fcf798d05f55c716192 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 14 Oct 2025 18:44:32 +0100 Subject: [PATCH 3/4] dissect-image: pass through DISSECT_IMAGE_VERITY_SHARE to mountfsd via varlink if set This ensures user services using RootImage=, ExtensionImages= etc. also try to reuse existing verity devices, like system services. Follow-up for 57d1ceffb3d98f69c2da511ed59a420a1cfa7e40 --- src/shared/dissect-image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index e44c307bbf..75dd428df8 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -4707,6 +4707,7 @@ int mountfsd_mount_image( SD_JSON_BUILD_PAIR("readOnly", SD_JSON_BUILD_BOOLEAN(FLAGS_SET(flags, DISSECT_IMAGE_MOUNT_READ_ONLY))), SD_JSON_BUILD_PAIR("growFileSystems", SD_JSON_BUILD_BOOLEAN(FLAGS_SET(flags, DISSECT_IMAGE_GROWFS))), SD_JSON_BUILD_PAIR_CONDITION(!!ps, "imagePolicy", SD_JSON_BUILD_STRING(ps)), + SD_JSON_BUILD_PAIR("veritySharing", SD_JSON_BUILD_BOOLEAN(FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))), SD_JSON_BUILD_PAIR("allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH)))); if (r < 0) return r; From 566a4bbbbf5a0600e77147422aa026ea27b08c74 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 14 Oct 2025 18:46:08 +0100 Subject: [PATCH 4/4] nspawn: enable verity sharing Just like RootImage=, ExtensionImages= etc, nspawn can make use of this to save a lot of time when starting containers that use an already open image, since the default was changed to disabled. Follow-up for 57d1ceffb3d98f69c2da511ed59a420a1cfa7e40 --- src/nspawn/nspawn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index ca5795aeb9..f157b53c29 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3830,6 +3830,7 @@ static DissectImageFlags determine_dissect_image_flags(void) { DISSECT_IMAGE_PIN_PARTITION_DEVICES | (arg_read_only ? DISSECT_IMAGE_READ_ONLY : DISSECT_IMAGE_FSCK|DISSECT_IMAGE_GROWFS) | DISSECT_IMAGE_ALLOW_USERSPACE_VERITY | + DISSECT_IMAGE_VERITY_SHARE | (arg_console_mode == CONSOLE_INTERACTIVE && arg_ask_password ? DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH : 0) | ((arg_userns_ownership == USER_NAMESPACE_OWNERSHIP_FOREIGN) ? DISSECT_IMAGE_FOREIGN_UID : (arg_userns_ownership != USER_NAMESPACE_OWNERSHIP_AUTO) ? DISSECT_IMAGE_IDENTITY_UID : 0);