linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Fwd: Some happening when using BIND mount with network namespace.
       [not found] <CAM7-yPTUgdbEeVvpWgGfB_eb==m0HPj8FpM0P+P-E0aBr35mgw@mail.gmail.com>
@ 2020-03-30  7:50 ` Yun Levi
  0 siblings, 0 replies; only message in thread
From: Yun Levi @ 2020-03-30  7:50 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel, netdev

[-- Attachment #1: Type: text/plain, Size: 1942 bytes --]

---------- Forwarded message ---------
From: Yun Levi <ppbuk5246@gmail.com>
Date: Mon, Mar 30, 2020 at 3:01 PM
Subject: Some happening when using BIND mount with network namespace.
To: Alexander Viro <viro@zeniv.linux.org.uk>, David S. Miller
<davem@davemloft.net>, Jakub Kicinski <kuba@kernel.org>, Guillaume
Nault <gnault@redhat.com>, Nicolas Dichtel
<nicolas.dichtel@6wind.com>, Eric Dumazet <edumazet@google.com>, David
Howells <dhowells@redhat.com>, Thomas Gleixner <tglx@linutronix.de>,
Li RongQing <lirongqing@baidu.com>, Johannes Berg
<johannes.berg@intel.com>, <linux-fsdevel@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <netdev@vger.kernel.org>


Hello. I'm Levi who is the beginner of Linux kernel.

When I use system calls related to network namespace, I got a some
problem in below scenario.
That's why I want to distinguish it's prohibit case for using unshare
and setns system call.

    1. Forking the process.
    2. [PARENT] Waiting the Child till the end.
    3. [CHILD] unshare for creating new network namespace
    4. [CHILD] Bind mount /proc/self/ns/net to some mount point.
    5. [CHILD] Exit child.
    6. [PARENT] Try to setns with binded mount point

In my analysis I confirm step 4 to 6 makes problem.
When we try to bind network namespace, it doesn't increase reference
count of related network namespace which saved on inode->i_private.
That's why network namespace made by unshare system call will be free on Step 5.

But on bind mountpoint, it still has network namespace pointer that was freed.
This makes some memory corruption on kernel when someone require to
allocate memory and give the pointer which allocated to the network
namespace made by Step 3.
That's why I can see the some Kernel Panic when I kill the some process...

So I attach some patch file to fix this problem.
But I want to distinguish it abnormal usage or not and this patch
should be applied.

Thank you for reading.

HTH.
Levi.

[-- Attachment #2: fix_netns_dangling_inode2.patch --]
[-- Type: application/octet-stream, Size: 2442 bytes --]

diff --git a/fs/namespace.c b/fs/namespace.c
index 85b5f7bea82e..88ebde39959f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -31,6 +31,10 @@
 #include <linux/fs_context.h>
 #include <linux/shmem_fs.h>

+#ifdef CONFIG_NET_NS
+#include <net/net_namespace.h>
+#endif
+
 #include "pnode.h"
 #include "internal.h"

@@ -1013,12 +1017,25 @@ vfs_submount(const struct dentry *mountpoint, struct file_system_type *type,
 }
 EXPORT_SYMBOL_GPL(vfs_submount);

+#ifdef CONFIG_NET_NS
+static bool is_net_ns_file(struct dentry *dentry)
+{
+	/* Is this a proxy for a mount namespace? */
+	return dentry->d_op == &ns_dentry_operations &&
+	       dentry->d_fsdata == &netns_operations;
+}
+#endif
+
 static struct mount *clone_mnt(struct mount *old, struct dentry *root,
 					int flag)
 {
 	struct super_block *sb = old->mnt.mnt_sb;
 	struct mount *mnt;
 	int err;
+#ifdef CONFIG_NET_NS
+	struct ns_common *ns = NULL;
+	struct net *net = NULL;
+#endif

 	mnt = alloc_vfsmnt(old->mnt_devname);
 	if (!mnt)
@@ -1035,6 +1052,20 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
 			goto out_free;
 	}

+#ifdef CONFIG_NET_NS
+	if (!(flag & CL_COPY_MNT_NS_FILE) && is_net_ns_file(root)) {
+		ns = get_proc_ns(d_inode(root));
+		if (ns == NULL || ns->ops->type != CLONE_NEWNET) {
+			err = -EINVAL;
+
+			goto out_free;
+		}
+
+		net = to_net_ns(ns);
+		net = get_net(net);
+	}
+#endif
+
 	mnt->mnt.mnt_flags = old->mnt.mnt_flags;
 	mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL);

diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 854d39ef1ca3..df3fb066a002 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -469,4 +469,11 @@ static inline void fnhe_genid_bump(struct net *net)
 	atomic_inc(&net->fnhe_genid);
 }

+#ifdef CONFIG_NET_NS
+static inline struct net *to_net_ns(struct ns_common *ns)
+{
+	return container_of(ns, struct net, ns);
+}
+#endif
+
 #endif /* __NET_NET_NAMESPACE_H */
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 757cc1d084e7..b6771c201805 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -1328,11 +1328,6 @@ static struct ns_common *netns_get(struct task_struct *task)
 	return net ? &net->ns : NULL;
 }

-static inline struct net *to_net_ns(struct ns_common *ns)
-{
-	return container_of(ns, struct net, ns);
-}
-
 static void netns_put(struct ns_common *ns)
 {
 	put_net(to_net_ns(ns));

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-03-30  7:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAM7-yPTUgdbEeVvpWgGfB_eb==m0HPj8FpM0P+P-E0aBr35mgw@mail.gmail.com>
2020-03-30  7:50 ` Fwd: Some happening when using BIND mount with network namespace Yun Levi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).