From: Karel Zak Date: Wed, 9 Apr 2025 10:15:57 +0000 (+0200) Subject: libmount: (subdir) restrict for real mounts only X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=437a271f7108f689d350f1b3d837490d3d283c3c;p=thirdparty%2Futil-linux.git libmount: (subdir) restrict for real mounts only It's now possible to use, for example, for bind operations, but it does not make sense as you can specify the target with the subdirectory. Signed-off-by: Karel Zak --- diff --git a/libmount/src/hook_subdir.c b/libmount/src/hook_subdir.c index 1e5d79958..7cbb2c88d 100644 --- a/libmount/src/hook_subdir.c +++ b/libmount/src/hook_subdir.c @@ -313,6 +313,7 @@ static int is_subdir_required(struct libmnt_context *cxt, int *rc, char **subdir struct libmnt_optlist *ol; struct libmnt_opt *opt; const char *dir = NULL; + unsigned long flags = 0; assert(cxt); assert(rc); @@ -328,16 +329,26 @@ static int is_subdir_required(struct libmnt_context *cxt, int *rc, char **subdir return 0; dir = mnt_opt_get_value(opt); - if (!dir || !*dir) { DBG(HOOK, ul_debug("failed to parse X-mount.subdir '%s'", dir)); *rc = -MNT_ERR_MOUNTOPT; - } else { - *subdir = strdup(dir); - if (!*subdir) - *rc = -ENOMEM; + return 0; + } + + *rc = mnt_optlist_get_flags(ol, &flags, cxt->map_linux, 0); + if (*rc) + return 0; + + if (flags & MS_REMOUNT || flags & MS_BIND || flags & MS_MOVE + || mnt_context_propagation_only(cxt)) { + DBG(HOOK, ul_debug("ignore subdir= (bind/move/remount/..)")); + return 0; } + *subdir = strdup(dir); + if (!*subdir) + *rc = -ENOMEM; + return *rc == 0; } diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc index bb4151225..95998ce2a 100644 --- a/sys-utils/mount.8.adoc +++ b/sys-utils/mount.8.adoc @@ -767,7 +767,9 @@ Note that *mount*(8) still sanitizes and canonicalizes the source and target pat Do not create and mount a loop device, even if the source of the mount is a regular file. **X-mount.subdir=**_directory_:: -Allow mounting a sub-directory of a filesystem instead of the root directory. For now, this feature is implemented by a temporary filesystem root-directory mount in an unshared namespace and then binding the sub-directory to the final mount point and unmounting the root of the filesystem. The sub-directory mount shows up atomically for the rest of the system although it is implemented by multiple *mount*(2) syscalls. +Allow mounting a subdirectory of a filesystem instead of the root directory. This is effective only when a new instance of a filesystem is attached to the system. The option is silently ignored for operations like remount, bind mount, or move. ++ +For now, this feature is implemented by a temporary filesystem root-directory mount in an unshared namespace and then binding the sub-directory to the final mount point and unmounting the root of the filesystem. The sub-directory mount shows up atomically for the rest of the system although it is implemented by multiple *mount*(2) syscalls. + Note that this feature will not work in session with an unshared private mount namespace (after *unshare --mount*) on old kernels or with *mount*(8) without support for file-descriptors-based mount kernel API. In this case, you need *unshare --mount --propagation shared*. +