util-linux: restrict X-mount.subdir to real mounts (#414405)
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
From cfb80587da7bf3d6a8eeb9b846702d6d731aa1c6 Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Wed, 9 Apr 2025 11:32:08 +0200
|
||||
Subject: [PATCH] libmount: (subdir) remove unused code
|
||||
|
||||
The optlist already handles quoted values, so there's no need to do it
|
||||
in the callers.
|
||||
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
(cherry picked from commit 5462fa3435544344727b8644205ae427dfd5fcba)
|
||||
---
|
||||
libmount/src/hook_subdir.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/libmount/src/hook_subdir.c b/libmount/src/hook_subdir.c
|
||||
index 5949af7d8..1e5d79958 100644
|
||||
--- a/libmount/src/hook_subdir.c
|
||||
+++ b/libmount/src/hook_subdir.c
|
||||
@@ -329,9 +329,6 @@ static int is_subdir_required(struct libmnt_context *cxt, int *rc, char **subdir
|
||||
|
||||
dir = mnt_opt_get_value(opt);
|
||||
|
||||
- if (dir && *dir == '"')
|
||||
- dir++;
|
||||
-
|
||||
if (!dir || !*dir) {
|
||||
DBG(HOOK, ul_debug("failed to parse X-mount.subdir '%s'", dir));
|
||||
*rc = -MNT_ERR_MOUNTOPT;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
From 22b91501d30a65d25ecf48ce5169ec70848117b8 Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Wed, 9 Apr 2025 12:15:57 +0200
|
||||
Subject: [PATCH] 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>
|
||||
(cherry picked from commit 437a271f7108f689d350f1b3d837490d3d283c3c)
|
||||
---
|
||||
libmount/src/hook_subdir.c | 21 ++++++++++++++++-----
|
||||
sys-utils/mount.8.adoc | 6 ++++--
|
||||
2 files changed, 20 insertions(+), 7 deletions(-)
|
||||
|
||||
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 6a17cd5eb..d9ce31fd4 100644
|
||||
--- a/sys-utils/mount.8.adoc
|
||||
+++ b/sys-utils/mount.8.adoc
|
||||
@@ -763,8 +763,10 @@ Note that *mount*(8) still sanitizes and canonicalizes the source and target pat
|
||||
*X-mount.noloop*::
|
||||
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 sub-directory from a filesystem instead of the root directory. For now, this feature is implemented by temporary filesystem root directory mount in unshared namespace and then bind the sub-directory to the final mount point and umount 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.
|
||||
+**X-mount.subdir=**_directory_::
|
||||
+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*.
|
||||
+
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -50,6 +50,9 @@ stdenv.mkDerivation (finalPackage: rec {
|
||||
./fix-darwin-build.patch
|
||||
# https://github.com/util-linux/util-linux/pull/3479 (fixes https://github.com/util-linux/util-linux/issues/3474)
|
||||
./fix-mount-regression.patch
|
||||
# https://github.com/util-linux/util-linux/pull/3530
|
||||
./libmount-subdir-remove-unused-code.patch
|
||||
./libmount-subdir-restrict-for-real-mounts-only.patch
|
||||
]
|
||||
++ lib.optionals (!stdenv.hostPlatform.isLinux) [
|
||||
(fetchurl {
|
||||
|
||||
Reference in New Issue
Block a user