]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: (subdir) restrict for real mounts only
authorKarel Zak <kzak@redhat.com>
Wed, 9 Apr 2025 10:15:57 +0000 (12:15 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 9 Apr 2025 11:38:45 +0000 (13:38 +0200)
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 <kzak@redhat.com>
libmount/src/hook_subdir.c
sys-utils/mount.8.adoc

index 1e5d79958a5cfe5d3b082689f050cd8e94380d3a..7cbb2c88d465a5f80ab67a0c145f7c39739826f0 100644 (file)
@@ -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;
 }
 
index bb4151225a060fdf78a6a2ad1fc51c21dadff4c2..95998ce2ad1ebdf85c58b1bef26fbe1b9e3773cd 100644 (file)
@@ -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*.
 +