util-linux: restrict X-mount.subdir to real mounts (#414405)

authored by Morgan Jones and committed by GitHub aee009fe befb2bee

+114
+31
pkgs/by-name/ut/util-linux/libmount-subdir-remove-unused-code.patch
··· 1 + From cfb80587da7bf3d6a8eeb9b846702d6d731aa1c6 Mon Sep 17 00:00:00 2001 2 + From: Karel Zak <kzak@redhat.com> 3 + Date: Wed, 9 Apr 2025 11:32:08 +0200 4 + Subject: [PATCH] libmount: (subdir) remove unused code 5 + 6 + The optlist already handles quoted values, so there's no need to do it 7 + in the callers. 8 + 9 + Signed-off-by: Karel Zak <kzak@redhat.com> 10 + (cherry picked from commit 5462fa3435544344727b8644205ae427dfd5fcba) 11 + --- 12 + libmount/src/hook_subdir.c | 3 --- 13 + 1 file changed, 3 deletions(-) 14 + 15 + diff --git a/libmount/src/hook_subdir.c b/libmount/src/hook_subdir.c 16 + index 5949af7d8..1e5d79958 100644 17 + --- a/libmount/src/hook_subdir.c 18 + +++ b/libmount/src/hook_subdir.c 19 + @@ -329,9 +329,6 @@ static int is_subdir_required(struct libmnt_context *cxt, int *rc, char **subdir 20 + 21 + dir = mnt_opt_get_value(opt); 22 + 23 + - if (dir && *dir == '"') 24 + - dir++; 25 + - 26 + if (!dir || !*dir) { 27 + DBG(HOOK, ul_debug("failed to parse X-mount.subdir '%s'", dir)); 28 + *rc = -MNT_ERR_MOUNTOPT; 29 + -- 30 + 2.49.0 31 +
+80
pkgs/by-name/ut/util-linux/libmount-subdir-restrict-for-real-mounts-only.patch
··· 1 + From 22b91501d30a65d25ecf48ce5169ec70848117b8 Mon Sep 17 00:00:00 2001 2 + From: Karel Zak <kzak@redhat.com> 3 + Date: Wed, 9 Apr 2025 12:15:57 +0200 4 + Subject: [PATCH] libmount: (subdir) restrict for real mounts only 5 + 6 + It's now possible to use, for example, for bind operations, but it 7 + does not make sense as you can specify the target with the 8 + subdirectory. 9 + 10 + Signed-off-by: Karel Zak <kzak@redhat.com> 11 + (cherry picked from commit 437a271f7108f689d350f1b3d837490d3d283c3c) 12 + --- 13 + libmount/src/hook_subdir.c | 21 ++++++++++++++++----- 14 + sys-utils/mount.8.adoc | 6 ++++-- 15 + 2 files changed, 20 insertions(+), 7 deletions(-) 16 + 17 + diff --git a/libmount/src/hook_subdir.c b/libmount/src/hook_subdir.c 18 + index 1e5d79958..7cbb2c88d 100644 19 + --- a/libmount/src/hook_subdir.c 20 + +++ b/libmount/src/hook_subdir.c 21 + @@ -313,6 +313,7 @@ static int is_subdir_required(struct libmnt_context *cxt, int *rc, char **subdir 22 + struct libmnt_optlist *ol; 23 + struct libmnt_opt *opt; 24 + const char *dir = NULL; 25 + + unsigned long flags = 0; 26 + 27 + assert(cxt); 28 + assert(rc); 29 + @@ -328,16 +329,26 @@ static int is_subdir_required(struct libmnt_context *cxt, int *rc, char **subdir 30 + return 0; 31 + 32 + dir = mnt_opt_get_value(opt); 33 + - 34 + if (!dir || !*dir) { 35 + DBG(HOOK, ul_debug("failed to parse X-mount.subdir '%s'", dir)); 36 + *rc = -MNT_ERR_MOUNTOPT; 37 + - } else { 38 + - *subdir = strdup(dir); 39 + - if (!*subdir) 40 + - *rc = -ENOMEM; 41 + + return 0; 42 + + } 43 + + 44 + + *rc = mnt_optlist_get_flags(ol, &flags, cxt->map_linux, 0); 45 + + if (*rc) 46 + + return 0; 47 + + 48 + + if (flags & MS_REMOUNT || flags & MS_BIND || flags & MS_MOVE 49 + + || mnt_context_propagation_only(cxt)) { 50 + + DBG(HOOK, ul_debug("ignore subdir= (bind/move/remount/..)")); 51 + + return 0; 52 + } 53 + 54 + + *subdir = strdup(dir); 55 + + if (!*subdir) 56 + + *rc = -ENOMEM; 57 + + 58 + return *rc == 0; 59 + } 60 + 61 + diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc 62 + index 6a17cd5eb..d9ce31fd4 100644 63 + --- a/sys-utils/mount.8.adoc 64 + +++ b/sys-utils/mount.8.adoc 65 + @@ -763,8 +763,10 @@ Note that *mount*(8) still sanitizes and canonicalizes the source and target pat 66 + *X-mount.noloop*:: 67 + Do not create and mount a loop device, even if the source of the mount is a regular file. 68 + 69 + -*X-mount.subdir=*__directory__:: 70 + -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. 71 + +**X-mount.subdir=**_directory_:: 72 + +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. 73 + ++ 74 + +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. 75 + + 76 + 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*. 77 + + 78 + -- 79 + 2.49.0 80 +
+3
pkgs/by-name/ut/util-linux/package.nix
··· 50 50 ./fix-darwin-build.patch 51 51 # https://github.com/util-linux/util-linux/pull/3479 (fixes https://github.com/util-linux/util-linux/issues/3474) 52 52 ./fix-mount-regression.patch 53 + # https://github.com/util-linux/util-linux/pull/3530 54 + ./libmount-subdir-remove-unused-code.patch 55 + ./libmount-subdir-restrict-for-real-mounts-only.patch 53 56 ] 54 57 ++ lib.optionals (!stdenv.hostPlatform.isLinux) [ 55 58 (fetchurl {