7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Josef Bacik [ Upstream commit 948e604aca8af30490accf7d46d44814ffa26f80 ] mntns_install() refuses to switch the mount namespace of a task that shares its fs_struct, since root and cwd of the others would move to a namespace they are not in. It looks at nsset->fs for that. If more than the mount namespace is asked for, that is a private copy made by prepare_nsset(), which has one user by definition; commit_nsset() then writes root and cwd of the copy to the fs_struct of the task. A thread of a process with two threads, pidfd of a task in another mount namespace: setns(pidfd, CLONE_NEWNS) -EINVAL setns(pidfd, CLONE_NEWNS | CLONE_NEWUTS) 0 and after the second call the other thread, still in the old mount namespace, has lost its cwd (/tmp became /) and sees the mounts of the other namespace under /. Look at the fs_struct that is going to be changed. The second call then fails with -EINVAL like the first one. Fixes: 303cc571d107 ("nsproxy: attach to namespaces via pidfds") Cc: stable@vger.kernel.org # v5.8+ Signed-off-by: Josef Bacik Signed-off-by: Christian Brauner (Amutable) Signed-off-by: Sasha Levin --- fs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index dd60123a0cb0c..cf627543572b3 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -6720,7 +6720,7 @@ static int mntns_install(struct nsset *nsset, struct ns_common *ns) if (is_anon_ns(mnt_ns)) return -EINVAL; - if (fs->users != 1) + if (current->fs->users != 1) return -EINVAL; get_mnt_ns(mnt_ns); -- 2.53.0