summaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2022-11-25 04:55:57 +0100
committerAl Viro <viro@zeniv.linux.org.uk>2022-11-25 04:55:57 +0100
commit61d8e42667716f71f2c26e327e66f2940d809f80 (patch)
tree6d4e523e378c75ac20c30127ee6444cf1e78c198 /fs/namespace.c
parentLinux 6.1-rc1 (diff)
downloadlinux-61d8e42667716f71f2c26e327e66f2940d809f80.tar.xz
linux-61d8e42667716f71f2c26e327e66f2940d809f80.zip
copy_mnt_ns(): handle a corner case (overmounted mntns bindings) saner
copy_mnt_ns() has the old tree copied, with mntns binding *and* anything bound on top of them skipped. Then it proceeds to walk both trees in parallel. Unfortunately, it doesn't get the "skip the stuff we'd skipped when copying" quite right. Consequences are minor (the ->mnt_root comparison will return the situation to sanity pretty soon and the worst we get is the unexpected subset of opened non-directories being switched to new namespace), but it's confusing enough and it's not hard to get the expected behaviour... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index df137ba19d37..c80f422084eb 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3515,8 +3515,9 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
q = next_mnt(q, new);
if (!q)
break;
+ // an mntns binding we'd skipped?
while (p->mnt.mnt_root != q->mnt.mnt_root)
- p = next_mnt(p, old);
+ p = next_mnt(skip_mnt_tree(p), old);
}
namespace_unlock();