aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2025-04-09 12:15:57 +0200
committerKarel Zak <kzak@redhat.com>2025-04-09 13:38:45 +0200
commit437a271f7108f689d350f1b3d837490d3d283c3c (patch)
treea7887c131defe9d3fd03e8092604149dbfe13c14
parent5462fa3435544344727b8644205ae427dfd5fcba (diff)
downloadutil-linux-437a271f7108f689d350f1b3d837490d3d283c3c.tar.gz
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 <kzak@redhat.com>
-rw-r--r--libmount/src/hook_subdir.c21
-rw-r--r--sys-utils/mount.8.adoc4
2 files changed, 19 insertions, 6 deletions
diff --git a/libmount/src/hook_subdir.c b/libmount/src/hook_subdir.c
index 1e5d79958a..7cbb2c88d4 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 bb4151225a..95998ce2ad 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*.
+