From: Luca Boccassi Date: Tue, 14 Oct 2025 22:32:54 +0000 (+0100) Subject: dissect: add support for verity-protected bare filesystems via mountfsd X-Git-Tag: v259-rc1~304^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fad01f798d1308fa6bd81eac1b13b3d14d9a5380;p=thirdparty%2Fsystemd.git dissect: add support for verity-protected bare filesystems via mountfsd Needed to implement support for RootHashSignature=/RootVerity=/RootHash= and friends when going through mountfsd, for example with user units, so that system and user units provide the same features at the same level --- diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 6ffe3b99891..f3bb1371be0 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -275,7 +275,7 @@ image. There's currently no option to configure the root hash for the /usr/ file system via the unit file directly. - + @@ -298,7 +298,7 @@ configure the root hash signature for the /usr/ via the unit file directly. - + @@ -319,7 +319,7 @@ Discoverable Partitions Specification. - + diff --git a/src/core/namespace.c b/src/core/namespace.c index 00d760f7ff4..6cf4f8b0a17 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -2604,6 +2604,7 @@ int setup_namespace(const NamespaceParameters *p, char **reterr_path) { p->root_image, userns_fd, p->root_image_policy, + p->verity, dissect_image_flags, &dissected_image); if (r < 0) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 7d921959cb1..332471a4099 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -2311,6 +2311,7 @@ static int run(int argc, char *argv[]) { arg_image, userns_fd, arg_image_policy, + &arg_verity_settings, arg_flags, &m); if (r < 0) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index f157b53c296..69f134bb754 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -6349,6 +6349,7 @@ static int run(int argc, char *argv[]) { arg_image, userns_fd, arg_image_policy, + &arg_verity_settings, dissect_image_flags, &dissected_image); if (r < 0) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index be40c772608..b597ee263a3 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -4513,6 +4513,7 @@ int verity_dissect_and_mount( src_fd >= 0 ? FORMAT_PROC_FD_PATH(src_fd) : src, userns_fd, image_policy, + verity, dissect_image_flags, &dissected_image); if (r < 0) @@ -4679,6 +4680,7 @@ int mountfsd_mount_image( const char *path, int userns_fd, const ImagePolicy *image_policy, + const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret) { @@ -4695,13 +4697,14 @@ int mountfsd_mount_image( }; _cleanup_(dissected_image_unrefp) DissectedImage *di = NULL; - _cleanup_close_ int image_fd = -EBADF; + _cleanup_close_ int image_fd = -EBADF, verity_data_fd = -EBADF; _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; _cleanup_free_ char *ps = NULL; const char *error_id; int r; assert(path); + assert(verity); assert(ret); r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem"); @@ -4736,6 +4739,16 @@ int mountfsd_mount_image( return log_error_errno(r, "Failed to format image policy to string: %m"); } + if (verity->data_path) { + verity_data_fd = open(verity->data_path, O_RDONLY|O_CLOEXEC); + if (verity_data_fd < 0) + return log_error_errno(errno, "Failed to open verity data file '%s': %m", verity->data_path); + + r = sd_varlink_push_dup_fd(vl, verity_data_fd); + if (r < 0) + return log_error_errno(r, "Failed to push verity data fd into varlink connection: %m"); + } + sd_json_variant *reply = NULL; r = varlink_callbo_and_log( vl, @@ -4748,6 +4761,9 @@ int mountfsd_mount_image( 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_CONDITION(verity_data_fd >= 0, "verityDataFileDescriptor", SD_JSON_BUILD_UNSIGNED(userns_fd >= 0 ? 2 : 1)), + JSON_BUILD_PAIR_IOVEC_HEX("verityRootHash", &((struct iovec) { .iov_base = verity->root_hash, .iov_len = verity->root_hash_size })), + JSON_BUILD_PAIR_IOVEC_BASE64("verityRootHashSignature", &((struct iovec) { .iov_base = verity->root_hash_sig, .iov_len = verity->root_hash_sig_size })), SD_JSON_BUILD_PAIR("allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH)))); if (r < 0) return r; diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index a050f107014..98fc440a44c 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -257,5 +257,5 @@ static inline const char* dissected_partition_fstype(const DissectedPartition *m int get_common_dissect_directory(char **ret); -int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, DissectImageFlags flags, DissectedImage **ret); +int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret); int mountfsd_mount_directory(const char *path, int userns_fd, DissectImageFlags flags, int *ret_mount_fd); diff --git a/test/units/TEST-50-DISSECT.mountfsd.sh b/test/units/TEST-50-DISSECT.mountfsd.sh index b6ff5012bf0..f4409f55bc3 100755 --- a/test/units/TEST-50-DISSECT.mountfsd.sh +++ b/test/units/TEST-50-DISSECT.mountfsd.sh @@ -72,6 +72,11 @@ if [ "$VERITY_SIG_SUPPORTED" -eq 1 ]; then systemd-run -M testuser@ --user --pipe --wait \ --property RootImage="$MINIMAL_IMAGE.gpt" \ test -e "/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity" + + systemd-run -M testuser@ --user --pipe --wait \ + --property RootImage="$MINIMAL_IMAGE.raw" \ + --property ExtensionImages=/tmp/app0.raw \ + sh -c "test -e \"/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity\" && test -e \"/dev/mapper/$(