mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/2] ovl: fix mount setup failing when override_creds drops CAP_SYS_ADMIN
@ 2026-09-24 11:28 Disha Goel
  2026-09-24 11:28 ` [PATCH 2/2] ovl: fix wrong layer paths in mountinfo for detached mount FDs Disha Goel
  0 siblings, 1 reply; 2+ messages in thread
From: Disha Goel @ 2026-09-24 11:28 UTC (permalink / raw)
  To: miklos, amir73il
  Cc: brauner, viro, jack, shuah, linux-unionfs, linux-fsdevel,
	linux-kselftest, linux-kernel, Disha Goel, stable

When a process drops CAP_SYS_ADMIN and calls fsconfig(FSCONFIG_SET_FLAG,
"override_creds"), overlayfs saves those restricted credentials in
ofs->creator_cred.  ovl_fill_super() then wrapped the entire mount setup
in with_ovl_creds(), switching to those restricted credentials for the
duration.

Mount setup calls clone_private_mount(), which checks CAP_SYS_ADMIN
against current credentials.  With restricted credentials active, this
check fails with -EPERM and the mount fails even though the calling
process is fully privileged.

Mount setup is a one-time privileged operation and must run under the
caller's credentials.  with_ovl_creds() belongs only in post-mount I/O
paths.  Remove it from ovl_fill_super().

Fixes: 539a0879de47 ("ovl: allow to specify override credentials")
Cc: stable@vger.kernel.org
Signed-off-by: Disha Goel <disgoel@linux.ibm.com>
---
 fs/overlayfs/super.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index bd0a3f9039d2..29f9489b8242 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1557,8 +1557,12 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
 			goto out_err;
 	}
 
-	with_ovl_creds(sb)
-		err = ovl_fill_super_creds(fc, sb);
+	/*
+	 * Mount setup must run under the caller's credentials, not
+	 * creator_cred: clone_private_mount() requires CAP_SYS_ADMIN,
+	 * which override_creds may have dropped.
+	 */
+	err = ovl_fill_super_creds(fc, sb);
 
 out_err:
 	if (err) {
-- 
2.45.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH 2/2] ovl: fix wrong layer paths in mountinfo for detached mount FDs
  2026-09-24 11:28 [PATCH 1/2] ovl: fix mount setup failing when override_creds drops CAP_SYS_ADMIN Disha Goel
@ 2026-09-24 11:28 ` Disha Goel
  0 siblings, 0 replies; 2+ messages in thread
From: Disha Goel @ 2026-09-24 11:28 UTC (permalink / raw)
  To: miklos, amir73il
  Cc: brauner, viro, jack, shuah, linux-unionfs, linux-fsdevel,
	linux-kselftest, linux-kernel, Disha Goel, stable

When overlayfs layers are passed as detached mount file descriptors
(opened with open_tree(OPEN_TREE_CLONE)), ovl_parse_layer() uses d_path()
to record the layer's path for display in mountinfo.

d_path() walks up the mount tree to the process's filesystem root.  For
detached mounts this walk stops at the anonymous namespace root instead
of the real system root, producing a short incorrect path like "/l1"
instead of the full absolute path.

Export mnt_is_anon() from fs/namespace.c to detect detached mounts.  In
ovl_parse_layer(), use dentry_path_raw() for detached mounts instead of
d_path().  dentry_path_raw() walks the dentry chain independent of mount
namespace and returns the correct fs-relative path.  The path is
display-only; the actual layer_path used for mounting is always correct.

Also fix the set_layers_via_detached_mount_fds selftest: the mountinfo
check strings were copy-pasted from the regular (non-detached) test and
expected absolute /tmp/ paths, causing the test to always fail.

Fixes: a08557d19ef4 ("ovl: specify layers via file descriptors")
Cc: stable@vger.kernel.org
Signed-off-by: Disha Goel <disgoel@linux.ibm.com>
---
 fs/namespace.c                                |  9 ++++++++
 fs/overlayfs/params.c                         | 14 ++++++++++-
 include/linux/mount.h                         |  1 +
 .../overlayfs/set_layers_via_fds.c            | 23 +++++++++++--------
 4 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index ae5dc64f8b45..9feefa0a517d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -363,6 +363,15 @@ bool __mnt_is_readonly(const struct vfsmount *mnt)
 }
 EXPORT_SYMBOL_GPL(__mnt_is_readonly);
 
+bool mnt_is_anon(struct vfsmount *mnt)
+{
+	struct mount *m = real_mount(mnt);
+	struct mnt_namespace *ns = READ_ONCE(m->mnt_ns);
+
+	return !IS_ERR_OR_NULL(ns) && is_anon_ns(ns);
+}
+EXPORT_SYMBOL_GPL(mnt_is_anon);
+
 static inline void mnt_inc_writers(struct mount *mnt)
 {
 #ifdef CONFIG_SMP
diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c
index c93fcaa45d4a..2758ff8426b7 100644
--- a/fs/overlayfs/params.c
+++ b/fs/overlayfs/params.c
@@ -477,7 +477,19 @@ static int ovl_parse_layer(struct fs_context *fc, struct fs_parameter *param,
 		layer_path = param->file->f_path;
 		path_get(&layer_path);
 
-		layer_name = d_path(&layer_path, buf, PATH_MAX);
+		/*
+		 * For detached mounts (open_tree(OPEN_TREE_CLONE)), d_path()
+		 * resolves against the anonymous namespace root and returns a
+		 * short fs-relative path rather than a full system path.  Use
+		 * dentry_path_raw() instead, which gives the path relative to
+		 * the filesystem root regardless of mount namespace.  The name
+		 * is display-only; layer_path itself is always correct.
+		 */
+		if (mnt_is_anon(layer_path.mnt))
+			layer_name = dentry_path_raw(layer_path.dentry,
+						     buf, PATH_MAX);
+		else
+			layer_name = d_path(&layer_path, buf, PATH_MAX);
 		if (IS_ERR(layer_name))
 			return PTR_ERR(layer_name);
 
diff --git a/include/linux/mount.h b/include/linux/mount.h
index acfe7ef86a1b..51e9f228c9d1 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -78,6 +78,7 @@ extern void mnt_make_shortterm(struct vfsmount *mnt);
 extern struct vfsmount *mnt_clone_internal(const struct path *path);
 extern bool __mnt_is_readonly(const struct vfsmount *mnt);
 extern bool mnt_may_suid(struct vfsmount *mnt);
+extern bool mnt_is_anon(struct vfsmount *mnt);
 
 extern struct vfsmount *clone_private_mount(const struct path *path);
 int mnt_get_write_access(struct vfsmount *mnt);
diff --git a/tools/testing/selftests/filesystems/overlayfs/set_layers_via_fds.c b/tools/testing/selftests/filesystems/overlayfs/set_layers_via_fds.c
index 7a293544233d..12d930fe46be 100644
--- a/tools/testing/selftests/filesystems/overlayfs/set_layers_via_fds.c
+++ b/tools/testing/selftests/filesystems/overlayfs/set_layers_via_fds.c
@@ -686,23 +686,28 @@ TEST_F(set_layers_via_fds, set_layers_via_detached_mount_fds)
 	while (getline(&line, &len, f_mountinfo) != -1) {
 		char *haystack = line;
 
-		if (strstr(haystack, "workdir=/tmp/w"))
+		/*
+		 * Detached mount FDs are resolved via dentry_path_raw(),
+		 * which gives a path relative to the underlying fs root
+		 * (e.g. "/u/upper", "/l1") rather than a full system path.
+		 */
+		if (strstr(haystack, "upperdir=/u/upper"))
 			layers_found[0] = true;
-		if (strstr(haystack, "upperdir=/tmp/u"))
+		if (strstr(haystack, "workdir=/u/work"))
 			layers_found[1] = true;
-		if (strstr(haystack, "lowerdir+=/tmp/l1"))
+		if (strstr(haystack, "lowerdir+=/l1"))
 			layers_found[2] = true;
-		if (strstr(haystack, "lowerdir+=/tmp/l2"))
+		if (strstr(haystack, "lowerdir+=/l2"))
 			layers_found[3] = true;
-		if (strstr(haystack, "lowerdir+=/tmp/l3"))
+		if (strstr(haystack, "lowerdir+=/l3"))
 			layers_found[4] = true;
-		if (strstr(haystack, "lowerdir+=/tmp/l4"))
+		if (strstr(haystack, "lowerdir+=/l4"))
 			layers_found[5] = true;
-		if (strstr(haystack, "datadir+=/tmp/d1"))
+		if (strstr(haystack, "datadir+=/d1"))
 			layers_found[6] = true;
-		if (strstr(haystack, "datadir+=/tmp/d2"))
+		if (strstr(haystack, "datadir+=/d2"))
 			layers_found[7] = true;
-		if (strstr(haystack, "datadir+=/tmp/d3"))
+		if (strstr(haystack, "datadir+=/d3"))
 			layers_found[8] = true;
 	}
 	free(line);
-- 
2.45.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-24 11:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-24 11:28 [PATCH 1/2] ovl: fix mount setup failing when override_creds drops CAP_SYS_ADMIN Disha Goel
2026-09-24 11:28 ` [PATCH 2/2] ovl: fix wrong layer paths in mountinfo for detached mount FDs Disha Goel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®