From a471b62e732a491f1abe42450352fb0f9b5b43ea Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Thu, 3 Sep 2026 09:45:29 +0200
Subject: [PATCH 1/3] lib/fileutils: fix unused parameter warnings without
 SYS_openat2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

On systems without SYS_openat2 (older kernels), ul_openat_resolve()
is a stub that returns -ENOSYS, making all parameters unused. With
-Werror=unused-parameter this breaks the build.

Move the #ifdef around the whole function so each branch has its own
declaration — the SYS_openat2 branch uses all parameters normally,
the fallback branch marks them __unused__.

Fixes: fb8e26535 ("libmount: pin source path with openat2() for restricted users")
Signed-off-by: Karel Zak <kzak@redhat.com>
---
 lib/fileutils.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/fileutils.c b/lib/fileutils.c
index 4d706c3a95a..f605b07bdd5 100644
--- a/lib/fileutils.c
+++ b/lib/fileutils.c
@@ -501,10 +501,10 @@ FILE *fopen_at_no_link(int dir, const char *filename,
 }
 #endif /* HAVE_OPENAT */
 
+#if defined(SYS_openat2)
 int ul_openat_resolve(int dirfd, const char *path, int flags,
 		      mode_t mode, unsigned long long resolve)
 {
-#if defined(SYS_openat2)
 	struct open_how how = {
 		.flags = (__u64) flags,
 		.mode = (__u64) mode,
@@ -512,11 +512,19 @@ int ul_openat_resolve(int dirfd, const char *path, int flags,
 	};
 
 	return syscall(SYS_openat2, dirfd, path, &how, sizeof(how));
+}
 #else
+int ul_openat_resolve(
+		int dirfd __attribute__((__unused__)),
+		const char *path __attribute__((__unused__)),
+		int flags __attribute__((__unused__)),
+		mode_t mode __attribute__((__unused__)),
+		unsigned long long resolve __attribute__((__unused__)))
+{
 	errno = ENOSYS;
 	return -1;
-#endif
 }
+#endif
 
 int ul_open_no_symlinks(const char *path, int flags, mode_t mode)
 {

From e06799ac325a881a297d2ffd6fe568cacdcd00ab Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Thu, 3 Sep 2026 10:01:29 +0200
Subject: [PATCH 2/3] libmount: use USE_LIBMOUNT_MOUNTFD_SUPPORT for idmap hook

The idmap hookset was originally guarded by HAVE_MOUNTFD_API (kernel
headers have the new mount syscalls) rather than
USE_LIBMOUNT_MOUNTFD_SUPPORT (libmount is built with mountfd support).

This was intentional (commit 9040c0900, 2022) -- the idea was to keep
idmap working even with --disable-libmount-mountfd-support by calling
the raw open_tree() syscall directly, while using an inner #ifdef
USE_LIBMOUNT_MOUNTFD_SUPPORT to optionally reuse the sysapi fd_tree.

This fine-grained approach broke when the CVE-2026-78410 fix replaced
the raw open_tree() call with mnt_open_tree(), which is only available
under USE_LIBMOUNT_MOUNTFD_SUPPORT. The build fails with
--disable-libmount-mountfd-support because mnt_open_tree() is
undeclared.

Rather than maintaining two code paths for a feature that fundamentally
depends on the new mount API, gate the entire idmap hookset on
USE_LIBMOUNT_MOUNTFD_SUPPORT -- consistent with how hookset_mount is
guarded. Remove the now-redundant inner #ifdef.

Also add a note to mount.8 that X-mount.idmap requires the new
fd-based mount API.

Addresses: https://github.com/util-linux/util-linux/issues/4598
Signed-off-by: Karel Zak <kzak@redhat.com>
---
 libmount/src/hook_idmap.c | 6 ++----
 libmount/src/hooks.c      | 2 +-
 libmount/src/version.c    | 2 +-
 4 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/libmount/src/hook_idmap.c b/libmount/src/hook_idmap.c
index a71c620f073..9a49573305b 100644
--- a/libmount/src/hook_idmap.c
+++ b/libmount/src/hook_idmap.c
@@ -32,7 +32,7 @@
 # include <linux/nsfs.h>
 #endif
 
-#if defined(HAVE_MOUNTFD_API) && defined(HAVE_LINUX_MOUNT_H)
+#ifdef USE_LIBMOUNT_MOUNTFD_SUPPORT
 
 typedef enum idmap_type_t {
 	ID_TYPE_UID,	/* uidmap entry */
@@ -317,7 +317,6 @@ static int hook_mount_post(
 	 * Once a mount has been attached to the filesystem it can't be
 	 * idmapped anymore. So create a new detached mount.
 	 */
-#ifdef USE_LIBMOUNT_MOUNTFD_SUPPORT
 	{
 		struct libmnt_sysapi *api = mnt_context_get_sysapi(cxt);
 
@@ -327,7 +326,6 @@ static int hook_mount_post(
 			DBG_OBJ(HOOK, hs, ul_debug(" reuse tree FD"));
 		}
 	}
-#endif
 	if (fd_tree < 0)
 		fd_tree = mnt_open_tree(AT_FDCWD, target,
 			    OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC |
@@ -544,4 +542,4 @@ const struct libmnt_hookset hookset_idmap =
 	.deinit = hookset_deinit
 };
 
-#endif /* HAVE_MOUNTFD_API && HAVE_LINUX_MOUNT_H */
+#endif /* USE_LIBMOUNT_MOUNTFD_SUPPORT */
diff --git a/libmount/src/hooks.c b/libmount/src/hooks.c
index 4d9c4affeca..bfb83dd52ef 100644
--- a/libmount/src/hooks.c
+++ b/libmount/src/hooks.c
@@ -45,7 +45,7 @@ static const struct libmnt_hookset *const hooksets[] =
 	&hookset_mount,
 #endif
 	&hookset_mount_legacy,
-#if defined(HAVE_MOUNTFD_API) && defined(HAVE_LINUX_MOUNT_H)
+#ifdef USE_LIBMOUNT_MOUNTFD_SUPPORT
 	&hookset_idmap,
 #endif
 	&hookset_owner
diff --git a/libmount/src/version.c b/libmount/src/version.c
index 165e2808792..b6f10ca744c 100644
--- a/libmount/src/version.c
+++ b/libmount/src/version.c
@@ -45,7 +45,7 @@ static const char *lib_features[] = {
 #ifdef USE_LIBMOUNT_SUPPORT_NAMESPACES
 	"namespaces",
 #endif
-#if defined(HAVE_MOUNTFD_API) && defined(HAVE_LINUX_MOUNT_H)
+#ifdef USE_LIBMOUNT_MOUNTFD_SUPPORT
 	"idmapping",
 #endif
 #ifdef USE_LIBMOUNT_MOUNTFD_SUPPORT
diff --git a/tools/config-gen.d/non-newmount.conf b/tools/config-gen.d/non-newmount.conf
new file mode 100644
index 00000000000..303b6cbad01
--- /dev/null
+++ b/tools/config-gen.d/non-newmount.conf
@@ -0,0 +1,3 @@
+include:core.conf
+
+--disable-libmount-mountfd-support
