From: Luca Boccassi Date: Wed, 27 Sep 2023 00:37:25 +0000 (+0100) Subject: mount-util: use new mount API for image mount tunnel X-Git-Tag: v255-rc1~360^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F29339%2Fhead;p=thirdparty%2Fsystemd.git mount-util: use new mount API for image mount tunnel --- diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 813c2bc5198..93e5af7e34d 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -1038,6 +1038,7 @@ static int mount_in_namespace( const ImagePolicy *image_policy, bool is_image) { + _cleanup_(dissected_image_unrefp) DissectedImage *img = NULL; _cleanup_close_pair_ int errno_pipe_fd[2] = PIPE_EBADF; _cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF, pidns_fd = -EBADF, chased_src_fd = -EBADF, new_mount_fd = -EBADF; @@ -1074,7 +1075,7 @@ static int mount_in_namespace( if (S_ISLNK(st.st_mode)) /* This shouldn't really happen, given that we just chased the symlinks above, but let's better be safe… */ return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Source directory %s can't be a symbolic link", src); - if (is_image || !mount_new_api_supported()) /* Fallback if we can't use the new mount API */ + if (!mount_new_api_supported()) /* Fallback if we can't use the new mount API */ return mount_in_namespace_legacy( chased_src_path, chased_src_fd, @@ -1091,24 +1092,43 @@ static int mount_in_namespace( image_policy, is_image); - new_mount_fd = open_tree( - chased_src_fd, - "", - OPEN_TREE_CLONE|OPEN_TREE_CLOEXEC|AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH); - if (new_mount_fd < 0) - return log_debug_errno( - errno, - "Failed to open mount point \"%s\": %m", - chased_src_path); - - if (read_only && mount_setattr(new_mount_fd, "", AT_EMPTY_PATH, - &(struct mount_attr) { - .attr_set = MOUNT_ATTR_RDONLY, - }, MOUNT_ATTR_SIZE_VER0) < 0) - return log_debug_errno( - errno, - "Failed to set mount flags for \"%s\": %m", - chased_src_path); + if (is_image) { + r = verity_dissect_and_mount( + chased_src_fd, + chased_src_path, + /* dest= */ NULL, + options, + image_policy, + /* required_host_os_release_id= */ NULL, + /* required_host_os_release_version_id= */ NULL, + /* required_host_os_release_sysext_level= */ NULL, + /* required_sysext_scope= */ NULL, + &img); + if (r < 0) + return log_debug_errno( + r, + "Failed to dissect and mount image %s: %m", + chased_src_path); + } else { + new_mount_fd = open_tree( + chased_src_fd, + "", + OPEN_TREE_CLONE|OPEN_TREE_CLOEXEC|AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH); + if (new_mount_fd < 0) + return log_debug_errno( + errno, + "Failed to open mount point \"%s\": %m", + chased_src_path); + + if (read_only && mount_setattr(new_mount_fd, "", AT_EMPTY_PATH, + &(struct mount_attr) { + .attr_set = MOUNT_ATTR_RDONLY, + }, MOUNT_ATTR_SIZE_VER0) < 0) + return log_debug_errno( + errno, + "Failed to set mount flags for \"%s\": %m", + chased_src_path); + } if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) return log_debug_errno(errno, "Failed to create pipe: %m"); @@ -1129,13 +1149,37 @@ static int mount_in_namespace( if (r == 0) { errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); - if (make_file_or_directory) { + if (make_file_or_directory) (void) mkdir_parents(dest, 0755); - (void) make_mount_point_inode_from_stat(&st, dest, 0700); - } - if (move_mount(new_mount_fd, "", -EBADF, dest, MOVE_MOUNT_F_EMPTY_PATH) < 0) { - (void) write(errno_pipe_fd[1], &errno, sizeof(errno)); + if (img) { + DissectImageFlags f = 0; + + if (make_file_or_directory) + f |= DISSECT_IMAGE_MKDIR; + + if (read_only) + f |= DISSECT_IMAGE_READ_ONLY; + + r = dissected_image_mount( + img, + dest, + /* uid_shift= */ UID_INVALID, + /* uid_range= */ UID_INVALID, + /* userns_fd= */ -EBADF, + f); + } else { + if (make_file_or_directory) + (void) make_mount_point_inode_from_stat(&st, dest, 0700); + + r = RET_NERRNO(move_mount(new_mount_fd, + "", + -EBADF, + dest, + MOVE_MOUNT_F_EMPTY_PATH)); + } + if (r < 0) { + (void) write(errno_pipe_fd[1], &r, sizeof(r)); errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); _exit(EXIT_FAILURE);