]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: add support for verity-protected bare filesystems via mountfsd
authorLuca Boccassi <luca.boccassi@gmail.com>
Tue, 14 Oct 2025 22:32:54 +0000 (23:32 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 16 Oct 2025 15:22:33 +0000 (16:22 +0100)
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

man/systemd.exec.xml
src/core/namespace.c
src/dissect/dissect.c
src/nspawn/nspawn.c
src/shared/dissect-image.c
src/shared/dissect-image.h
test/units/TEST-50-DISSECT.mountfsd.sh

index 6ffe3b99891be66e6fe750d50ca6d8cf0af756a2..f3bb1371be0b24207db935ece1e56960f3100d54 100644 (file)
         image. There's currently no option to configure the root hash for the <filename>/usr/</filename> file
         system via the unit file directly.</para>
 
-        <xi:include href="system-only.xml" xpointer="singular"/>
+        <xi:include href="system-or-user-ns-mountfsd.xml" xpointer="singular"/>
 
         <xi:include href="version-info.xml" xpointer="v246"/></listitem>
       </varlistentry>
         configure the root hash signature for the <filename>/usr/</filename> via the unit file
         directly.</para>
 
-        <xi:include href="system-only.xml" xpointer="singular"/>
+        <xi:include href="system-or-user-ns-mountfsd.xml" xpointer="singular"/>
 
         <xi:include href="version-info.xml" xpointer="v246"/></listitem>
       </varlistentry>
         <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">
           Discoverable Partitions Specification</ulink>.</para>
 
-        <xi:include href="system-only.xml" xpointer="singular"/>
+        <xi:include href="system-or-user-ns-mountfsd.xml" xpointer="singular"/>
 
         <xi:include href="version-info.xml" xpointer="v246"/></listitem>
       </varlistentry>
index 00d760f7ff453c478c29d89f28b98e20a310b4a4..6cf4f8b0a1792d8108781405a8f50b0940ec4c80 100644 (file)
@@ -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)
index 7d921959cb17f5629333e9c51b7db8fc5a1c8a7e..332471a4099c82c0111388b404151952b106cd24 100644 (file)
@@ -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)
index f157b53c296157196d8d6bbe9248465b13669e65..69f134bb754256ba7bc194b8263dfe0b8727a4d1 100644 (file)
@@ -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)
index be40c772608fefc9bde02ef4d42e111bc275291e..b597ee263a36a50233de189750e324d3726723d0 100644 (file)
@@ -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;
index a050f1070148e11a45b1c3a14fe4b766fea4d315..98fc440a44cb975cfda8f43d6b31816a00320b97 100644 (file)
@@ -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);
index b6ff5012bf07a83ecc44a1a1fe95d9ea0db6495f..f4409f55bc3b3c55893676fff2ccfc24b8a06a29 100755 (executable)
@@ -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/$(</tmp/app0.roothash)-verity\""
 fi
 
 # Install key in keychain