From: Mike Yuan Date: Fri, 7 Nov 2025 22:06:03 +0000 (+0100) Subject: mount-util: introduce fsmount_credentials_fs() X-Git-Tag: v259-rc1~92^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e4c7e4c27a057a4f6be2ba711a0304cdf4894e65;p=thirdparty%2Fsystemd.git mount-util: introduce fsmount_credentials_fs() While at it, remove effectively unused size and ro params. --- diff --git a/src/core/exec-credential.c b/src/core/exec-credential.c index 22ada50a5fa..7c1c98349a8 100644 --- a/src/core/exec-credential.c +++ b/src/core/exec-credential.c @@ -1014,7 +1014,7 @@ static int setup_credentials_internal( if (!final_mounted) /* Nothing is mounted on the workspace yet, let's try to mount a new tmpfs if * not using the final place. */ - r = mount_credentials_fs(workspace, CREDENTIALS_TOTAL_SIZE_MAX, /* ro= */ false); + r = mount_credentials_fs(workspace); if (final_mounted || r < 0) { /* If using final place or failed to mount new tmpfs, make a bind mount from * the final to the workspace, so that we can make it writable there. */ diff --git a/src/core/import-creds.c b/src/core/import-creds.c index 0f35514079e..e0df078448f 100644 --- a/src/core/import-creds.c +++ b/src/core/import-creds.c @@ -103,7 +103,7 @@ static int acquire_credential_directory(ImportCredentialsContext *c, const char (void) mount_nofollow_verbose(LOG_WARNING, NULL, path, NULL, MS_BIND|MS_REMOUNT|credentials_fs_mount_flags(/* ro= */ false), NULL); else if (with_mount) /* If not a mount point yet, and the credentials are not encrypted, then let's try to mount a no-swap fs there */ - (void) mount_credentials_fs(path, CREDENTIALS_TOTAL_SIZE_MAX, /* ro= */ false); + (void) mount_credentials_fs(path); c->target_dir_fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC); if (c->target_dir_fd < 0) diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index dcdc42b00ae..fb3f5b52068 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -7,6 +7,7 @@ #include "alloc-util.h" #include "chase.h" +#include "creds-util.h" #include "dissect-image.h" #include "errno-util.h" #include "extract-word.h" @@ -1831,58 +1832,65 @@ unsigned long credentials_fs_mount_flags(bool ro) { return MS_NODEV|MS_NOEXEC|MS_NOSUID|ms_nosymfollow_supported()|(ro ? MS_RDONLY : 0); } -int mount_credentials_fs(const char *path, size_t size, bool ro) { - _cleanup_free_ char *opts = NULL; - int r, noswap_supported; +int fsmount_credentials_fs(int *ret_fsfd) { + _cleanup_close_ int fs_fd = -EBADF; + char size_str[DECIMAL_STR_MAX(uint64_t)]; /* Mounts a file system we can place credentials in, i.e. with tight access modes right from the * beginning, and ideally swapping turned off. In order of preference: * - * 1. tmpfs if it supports "noswap" + * 1. tmpfs if it supports "noswap" (needs kernel >= 6.3) * 2. ramfs - * 3. tmpfs if it doesn't support "noswap" + * 3. tmpfs without "noswap" */ - noswap_supported = mount_option_supported("tmpfs", "noswap", NULL); /* Check explicitly to avoid kmsg noise */ - if (noswap_supported > 0) { - _cleanup_free_ char *noswap_opts = NULL; + fs_fd = fsopen("tmpfs", FSOPEN_CLOEXEC); + if (fs_fd < 0) + return -errno; - if (asprintf(&noswap_opts, "mode=0700,nr_inodes=1024,size=%zu,noswap", size) < 0) - return -ENOMEM; + if (fsconfig(fs_fd, FSCONFIG_SET_STRING, "nr_inodes", "1024", 0) < 0) + return -errno; - /* Best case: tmpfs with noswap (needs kernel >= 6.3) */ + xsprintf(size_str, "%" PRIu64, CREDENTIALS_TOTAL_SIZE_MAX); + if (fsconfig(fs_fd, FSCONFIG_SET_STRING, "size", size_str, 0) < 0) + return -errno; - r = mount_nofollow_verbose( - LOG_DEBUG, - "tmpfs", - path, - "tmpfs", - credentials_fs_mount_flags(ro), - noswap_opts); - if (r >= 0) - return r; + if (fsconfig(fs_fd, FSCONFIG_SET_FLAG, "noswap", NULL, 0) < 0) { + if (errno != EINVAL) + return -errno; + + int ramfs_fd = fsopen("ramfs", FSOPEN_CLOEXEC); + if (ramfs_fd >= 0) + close_and_replace(fs_fd, ramfs_fd); } - r = mount_nofollow_verbose( - LOG_DEBUG, - "ramfs", - path, - "ramfs", - credentials_fs_mount_flags(ro), - "mode=0700"); - if (r >= 0) - return r; + if (fsconfig(fs_fd, FSCONFIG_SET_STRING, "mode", "0700", 0) < 0) + return -errno; - if (asprintf(&opts, "mode=0700,nr_inodes=1024,size=%zu", size) < 0) - return -ENOMEM; + if (fsconfig(fs_fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0) < 0) + return -errno; - return mount_nofollow_verbose( - LOG_DEBUG, - "tmpfs", - path, - "tmpfs", - credentials_fs_mount_flags(ro), - opts); + int mfd = fsmount(fs_fd, FSMOUNT_CLOEXEC, + ms_flags_to_mount_attr(credentials_fs_mount_flags(/* ro = */ false))); + if (mfd < 0) + return -errno; + + if (ret_fsfd) + *ret_fsfd = TAKE_FD(fs_fd); + + return mfd; +} + +int mount_credentials_fs(const char *path) { + _cleanup_close_ int mfd = -EBADF; + + assert(path); + + mfd = fsmount_credentials_fs(/* ret_fsfd = */ NULL); + if (mfd < 0) + return mfd; + + return RET_NERRNO(move_mount(mfd, "", AT_FDCWD, path, MOVE_MOUNT_F_EMPTY_PATH)); } int make_fsmount( diff --git a/src/shared/mount-util.h b/src/shared/mount-util.h index c5968dc5659..c607875375f 100644 --- a/src/shared/mount-util.h +++ b/src/shared/mount-util.h @@ -159,7 +159,8 @@ int make_mount_point_inode_from_path(const char *source, const char *dest, mode_ int trigger_automount_at(int dir_fd, const char *path); unsigned long credentials_fs_mount_flags(bool ro); -int mount_credentials_fs(const char *path, size_t size, bool ro); +int fsmount_credentials_fs(int *ret_fsfd); +int mount_credentials_fs(const char *path); int make_fsmount(int error_log_level, const char *what, const char *type, unsigned long flags, const char *options, int userns_fd);