Skip to contentSkip to conversation

check_mnt() breaks namespaces

PATCH Herbert Poetzl 2 participants 2 messages Jul 14, 2004 – Jul 18, 2004 VFS

lore
Share & tools
lore
#0 lore raw

Hi Andrew!

the check_mnt() in do_add_mount() breaks namespaces in that way, that it forbids mounting single sb filesystems (like procfs) to be mounted in different namespaces ...

I guess this is unintentional, but who knows ... (this was introduced in 2.6.8-rc1, 2.6.7-bk20 works as expected)

something like this (untested) fixes? it ...

fs/namei.c 2004-07-12 14:59:08.000000000 +0200 renamed from fs/namei.c 2004-07-12 14:47:08.000000000 +0200 +0 -3
diff -NurpP --minimal linux-2.6.8-rc1/fs/namei.c linux-2.6.8-rc1-fix/fs/namei.c
@@ -794,7 +819,5 @@ int do_add_mount(struct vfsmount *newmnt
                ;
-       err = -EINVAL;
-       if (!check_mnt(nd->mnt))
-               goto unlock;
 
        /* Refuse the same filesystem on the same mount point */
        err = -EBUSY;

best,
Herbert

#1 lore raw

It's not check_mnt(), it's breakage in copy_namespace().
It forgets to switch new field (->mnt_namespace) in the vfsmounts of new namespace.

namespace.c renamed from RC8-rc2/fs/namespace.c +13 -11
@@ -1037,6 +1037,7 @@
 	struct namespace *new_ns;
 	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
 	struct fs_struct *fs = tsk->fs;
+	struct vfsmount *p, *q;
 
 	if (!namespace)
 		return 0;
@@ -1071,14 +1072,16 @@
 	list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
 	spin_unlock(&vfsmount_lock);
 
-	/* Second pass: switch the tsk->fs->* elements */
-	if (fs) {
-		struct vfsmount *p, *q;
-		write_lock(&fs->lock);
-
-		p = namespace->root;
-		q = new_ns->root;
-		while (p) {
+	/*
+	 * Second pass: switch the tsk->fs->* elements and mark new vfsmounts
+	 * as belonging to new namespace.  We have already acquired a private
+	 * fs_struct, so tsk->fs->lock is not needed.
+	 */
+	p = namespace->root;
+	q = new_ns->root;
+	while (p) {
+		q->mnt_namespace = new_ns;
+		if (fs) {
 			if (p == fs->rootmnt) {
 				rootmnt = p;
 				fs->rootmnt = mntget(q);
@@ -1091,10 +1094,9 @@
 				altrootmnt = p;
 				fs->altrootmnt = mntget(q);
 			}
-			p = next_mnt(p, namespace->root);
-			q = next_mnt(q, new_ns->root);
 		}
-		write_unlock(&fs->lock);
+		p = next_mnt(p, namespace->root);
+		q = next_mnt(q, new_ns->root);
 	}
 	up_write(&tsk->namespace->sem);