diff --git a/src/core/namespace.c b/src/core/namespace.c index a731c93860..9d53d98a16 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -1156,7 +1156,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; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 14519ead70..c16d98b127 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -3452,6 +3452,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, @@ -3470,14 +3471,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); diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 032126627c..3302eb69fd 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -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); diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index c75c02f5be..fd6a5c09b5 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -790,6 +790,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; @@ -827,9 +828,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); @@ -874,7 +876,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) diff --git a/test/units/testsuite-50.sh b/test/units/testsuite-50.sh index 793795efdd..2f0dbbeae5 100755 --- a/test/units/testsuite-50.sh +++ b/test/units/testsuite-50.sh @@ -279,7 +279,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