Commit 4954346d authored by KONDO KAZUMA(近藤 和真)'s avatar KONDO KAZUMA(近藤 和真) Committed by Al Viro
Browse files

fs: allow clone_private_mount() for a path on real rootfs



Mounting overlayfs with a directory on real rootfs (initramfs)
as upperdir has failed with following message since commit
db04662e ("fs: allow detached mounts in clone_private_mount()").

  [    4.080134] overlayfs: failed to clone upperpath

Overlayfs mount uses clone_private_mount() to create internal mount
for the underlying layers.

The commit made clone_private_mount() reject real rootfs because
it does not have a parent mount and is in the initial mount namespace,
that is not an anonymous mount namespace.

This issue can be fixed by modifying the permission check
of clone_private_mount() following [1].

Reviewed-by: default avatarChristian Brauner <brauner@kernel.org>
Fixes: db04662e ("fs: allow detached mounts in clone_private_mount()")
Link: https://lore.kernel.org/all/20250514190252.GQ2023217@ZenIV/ [1]
Link: https://lore.kernel.org/all/20250506194849.GT2023217@ZenIV/


Suggested-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarKazuma Kondo <kazuma-kondo@nec.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent d8cc0362
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -2493,18 +2493,19 @@ struct vfsmount *clone_private_mount(const struct path *path)
	if (IS_MNT_UNBINDABLE(old_mnt))
		return ERR_PTR(-EINVAL);

	if (mnt_has_parent(old_mnt)) {
		if (!check_mnt(old_mnt))
			return ERR_PTR(-EINVAL);
	} else {
		if (!is_mounted(&old_mnt->mnt))
			return ERR_PTR(-EINVAL);

		/* Make sure this isn't something purely kernel internal. */
		if (!is_anon_ns(old_mnt->mnt_ns))
	/*
	 * Make sure the source mount is acceptable.
	 * Anything mounted in our mount namespace is allowed.
	 * Otherwise, it must be the root of an anonymous mount
	 * namespace, and we need to make sure no namespace
	 * loops get created.
	 */
	if (!check_mnt(old_mnt)) {
		if (!is_mounted(&old_mnt->mnt) ||
			!is_anon_ns(old_mnt->mnt_ns) ||
			mnt_has_parent(old_mnt))
			return ERR_PTR(-EINVAL);

		/* Make sure we don't create mount namespace loops. */
		if (!check_for_nsfs_mounts(old_mnt))
			return ERR_PTR(-EINVAL);
	}