Commit 3b5260d1 authored by Al Viro's avatar Al Viro
Browse files

Don't propagate mounts into detached trees

All versions up to 6.14 did not propagate mount events into detached
tree.  Shortly after 6.14 a merge of vfs-6.15-rc1.mount.namespace
(130e696a) has changed that.

Unfortunately, that has caused userland regressions (reported in
https://lore.kernel.org/all/CAOYeF9WQhFDe+BGW=Dp5fK8oRy5AgZ6zokVyTj1Wp4EUiYgt4w@mail.gmail.com/

)

Straight revert wouldn't be an option - in particular, the variant in 6.14
had a bug that got fixed in d1ddc6f1 ("fix IS_MNT_PROPAGATING uses")
and we don't want to bring the bug back.

This is a modification of manual revert posted by Christian, with changes
needed to avoid reintroducing the breakage in scenario described in
d1ddc6f1.

Cc: stable@vger.kernel.org
Reported-by: default avatarAllison Karlitskaya <lis@redhat.com>
Tested-by: default avatarAllison Karlitskaya <lis@redhat.com>
Acked-by: default avatarChristian Brauner <brauner@kernel.org>
Co-developed-by: default avatarChristian Brauner <brauner@kernel.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent d1ddc6f1
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -7,10 +7,6 @@

extern struct list_head notify_list;

typedef __u32 __bitwise mntns_flags_t;

#define MNTNS_PROPAGATING	((__force mntns_flags_t)(1 << 0))

struct mnt_namespace {
	struct ns_common	ns;
	struct mount *	root;
@@ -37,7 +33,6 @@ struct mnt_namespace {
	struct rb_node		mnt_ns_tree_node; /* node in the mnt_ns_tree */
	struct list_head	mnt_ns_list; /* entry in the sequential list of mounts namespace */
	refcount_t		passive; /* number references not pinning @mounts */
	mntns_flags_t		mntns_flags;
} __randomize_layout;

struct mnt_pcp {
+2 −13
Original line number Diff line number Diff line
@@ -3648,7 +3648,7 @@ static int do_move_mount(struct path *old_path,
	if (!(attached ? check_mnt(old) : is_anon_ns(ns)))
		goto out;

	if (is_anon_ns(ns)) {
	if (is_anon_ns(ns) && ns == p->mnt_ns) {
		/*
		 * Ending up with two files referring to the root of the
		 * same anonymous mount namespace would cause an error
@@ -3656,16 +3656,7 @@ static int do_move_mount(struct path *old_path,
		 * twice into the mount tree which would be rejected
		 * later. But be explicit about it right here.
		 */
		if ((is_anon_ns(p->mnt_ns) && ns == p->mnt_ns))
		goto out;

		/*
		 * If this is an anonymous mount tree ensure that mount
		 * propagation can detect mounts that were just
		 * propagated to the target mount tree so we don't
		 * propagate onto them.
		 */
		ns->mntns_flags |= MNTNS_PROPAGATING;
	} else if (is_anon_ns(p->mnt_ns)) {
		/*
		 * Don't allow moving an attached mount tree to an
@@ -3722,8 +3713,6 @@ static int do_move_mount(struct path *old_path,
	if (attached)
		put_mountpoint(old_mp);
out:
	if (is_anon_ns(ns))
		ns->mntns_flags &= ~MNTNS_PROPAGATING;
	unlock_mount(mp);
	if (!err) {
		if (attached) {
+2 −2
Original line number Diff line number Diff line
@@ -231,8 +231,8 @@ static int propagate_one(struct mount *m, struct mountpoint *dest_mp)
	/* skip if mountpoint isn't visible in m */
	if (!is_subdir(dest_mp->m_dentry, m->mnt.mnt_root))
		return 0;
	/* skip if m is in the anon_ns we are emptying */
	if (m->mnt_ns->mntns_flags & MNTNS_PROPAGATING)
	/* skip if m is in the anon_ns */
	if (is_anon_ns(m->mnt_ns))
		return 0;

	if (peers(m, last_dest)) {