]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: fix dm-verity auto-discovery in MountImageUnit()
authorLuca Boccassi <bluca@debian.org>
Wed, 6 Apr 2022 16:25:35 +0000 (17:25 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 7 Apr 2022 16:31:04 +0000 (17:31 +0100)
The implementation of MountImageUnit()/systemctl mount-image was
changed to use a /proc/self/fd path as the source, but that causes
the dm-verity files autodiscovery to fail, as it looks for files
in the same directory as the image.

Use the original file path when setting up dm-verity.

src/core/namespace.c
src/shared/dissect-image.c
src/shared/dissect-image.h
src/shared/mount-util.c
test/units/testsuite-50.sh

index 4ede17788b142ab32b25e9f2b9eedb2c80fa7055..e6aa7b6473eaa602abe1c609a800f94e1061b50a 100644 (file)
@@ -1216,7 +1216,7 @@ static int mount_image(const MountEntry *m, const char *root_directory) {
         }
 
         r = verity_dissect_and_mount(
-                                mount_entry_source(m), mount_entry_path(m), m->image_options,
+                                /* src_fd= */ -1, mount_entry_source(m), mount_entry_path(m), m->image_options,
                                 host_os_release_id, host_os_release_version_id, host_os_release_sysext_level, NULL);
         if (r == -ENOENT && m->ignore)
                 return 0;
index e63b168c24a320466f1c93d679d21b58c62c6988..6e287ecac72a2714d56045b2b4420478976e704f 100644 (file)
@@ -3448,6 +3448,7 @@ static const char *const partition_designator_table[] = {
 };
 
 int verity_dissect_and_mount(
+                int src_fd,
                 const char *src,
                 const char *dest,
                 const MountOptions *options,
@@ -3466,14 +3467,17 @@ int verity_dissect_and_mount(
         assert(src);
         assert(dest);
 
+        /* We might get an FD for the image, but we use the original path to look for the dm-verity files */
         r = verity_settings_load(&verity, src, NULL, NULL);
         if (r < 0)
                 return log_debug_errno(r, "Failed to load root hash: %m");
 
         dissect_image_flags = verity.data_path ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0;
 
+        /* Note that we don't use loop_device_make here, as the FD is most likely O_PATH which would not be
+         * accepted by LOOP_CONFIGURE, so just let loop_device_make_by_path reopen it as a regular FD. */
         r = loop_device_make_by_path(
-                        src,
+                        src_fd >= 0 ? FORMAT_PROC_FD_PATH(src_fd) : src,
                         -1,
                         verity.data_path ? 0 : LO_FLAGS_PARTSCAN,
                         &loop_device);
index b74adf5f8de47f5df049bac59609213c70fed0ee..1bc8d2ef9a3eb069212c494f5d3c37baf12851b4 100644 (file)
@@ -285,4 +285,4 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
 
 int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device, DecryptedImage **ret_decrypted_image);
 
-int verity_dissect_and_mount(const char *src, const char *dest, const MountOptions *options, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_sysext_scope);
+int verity_dissect_and_mount(int src_fd, const char *src, const char *dest, const MountOptions *options, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_sysext_scope);
index 78f06b25fee32e20af464adf6c6ef8dea840d4af..e76e4a0b389c16b3beab1905ad8bd63321d01453 100644 (file)
@@ -789,6 +789,7 @@ static int mount_in_namespace(
         bool mount_slave_created = false, mount_slave_mounted = false,
                 mount_tmp_created = false, mount_tmp_mounted = false,
                 mount_outside_created = false, mount_outside_mounted = false;
+        _cleanup_free_ char *chased_src_path = NULL;
         struct stat st, self_mntns_st;
         pid_t child;
         int r;
@@ -826,9 +827,10 @@ static int mount_in_namespace(
         if (r < 0)
                 return log_debug_errno(r == -ENOENT ? SYNTHETIC_ERRNO(EOPNOTSUPP) : r, "Target does not allow propagation of mount points");
 
-        r = chase_symlinks(src, NULL, CHASE_TRAIL_SLASH, NULL, &chased_src_fd);
+        r = chase_symlinks(src, NULL, 0, &chased_src_path, &chased_src_fd);
         if (r < 0)
                 return log_debug_errno(r, "Failed to resolve source path of %s: %m", src);
+        log_debug("Chased source path of %s to %s", src, chased_src_path);
 
         if (fstat(chased_src_fd, &st) < 0)
                 return log_debug_errno(errno, "Failed to stat() resolved source path %s: %m", src);
@@ -873,7 +875,7 @@ static int mount_in_namespace(
         mount_tmp_created = true;
 
         if (is_image)
-                r = verity_dissect_and_mount(FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, options, NULL, NULL, NULL, NULL);
+                r = verity_dissect_and_mount(chased_src_fd, chased_src_path, mount_tmp, options, NULL, NULL, NULL, NULL);
         else
                 r = mount_follow_verbose(LOG_DEBUG, FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, NULL, MS_BIND, NULL);
         if (r < 0)
index 6aabbd139c39da6ea797824f5a6cceca04f8c402..2f1844ccf7463f717c70bdff87dd6b70e0dea907 100755 (executable)
@@ -285,7 +285,7 @@ Type=notify
 RemainAfterExit=yes
 MountAPIVFS=yes
 PrivateTmp=yes
-ExecStart=/bin/sh -c 'systemd-notify --ready; while ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do sleep 0.1; done; mount | grep -F "/tmp/img" | grep -q -F "nosuid"'
+ExecStart=/bin/sh -c 'systemd-notify --ready; while ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do sleep 0.1; done; mount | grep -F "/dev/mapper/${roothash}-verity" | grep -q -F "nosuid"'
 EOF
 systemctl start testservice-50d.service