[lxc-devel] [lxc/master] Fixed file descriptor leak for network namespace

Rachid-Koucha on Github lxc-bot at linuxcontainers.org
Sat Jun 15 13:18:50 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1320 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190615/55ddbf9c/attachment.bin>
-------------- next part --------------
From aa0c0e7b8a6394bc1c124ec93f58128f101ed68a Mon Sep 17 00:00:00 2001
From: Rachid Koucha <47061324+Rachid-Koucha at users.noreply.github.com>
Date: Sat, 15 Jun 2019 15:17:50 +0200
Subject: [PATCH] Fixed file descriptor leak for network namespace

In privileged mode, the container startup looses a file descriptor for "handler->nsfd[LX_NS_NET]". At line 1782, we preserve the namespaces file descriptor (in privileged mode, the network namespace is also preserved) :
	for (i = 0; i < LXC_NS_MAX; i++)
		if (handler->ns_on_clone_flags & ns_info[i].clone_flag)
			INFO("Cloned %s", ns_info[i].flag_name);

	if (!lxc_try_preserve_namespaces(handler, handler->ns_on_clone_flags, handler->pid)) {
		ERROR("Failed to preserve cloned namespaces for lxc.hook.stop");
		goto out_delete_net;
	}

Then at line 1830, we preserve one more time the network namespace :
		ret = lxc_try_preserve_ns(handler->pid, "net");
		if (ret < 0) {
			if (ret != -EOPNOTSUPP) {
				SYSERROR("Failed to preserve net namespace");
				goto out_delete_net;
			}
The latter overwrites the file descriptor already stored in handler->nsfd[LXC_NS_NET] at line 1786.

So, this fix checks that the entry is not already filled.

Signed-off-by: Rachid Koucha <rachid.koucha at gmail.com>
---
 src/lxc/start.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index d6477fd1fc..eaec20f964 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1826,23 +1826,24 @@ static int lxc_spawn(struct lxc_handler *handler)
 	if (!cgroup_ops->chown(cgroup_ops, handler->conf))
 		goto out_delete_net;
 
-	/* Now we're ready to preserve the network namespace */
-	ret = lxc_try_preserve_ns(handler->pid, "net");
-	if (ret < 0) {
-		if (ret != -EOPNOTSUPP) {
-			SYSERROR("Failed to preserve net namespace");
-			goto out_delete_net;
+	/* If not done yet, we're now ready to preserve the network namespace */
+	if (handler->nsfd[LXC_NS_NET] < 0) {
+		ret = lxc_try_preserve_ns(handler->pid, "net");
+		if (ret < 0) {
+			if (ret != -EOPNOTSUPP) {
+				SYSERROR("Failed to preserve net namespace");
+				goto out_delete_net;
+			}
+		} else {
+			handler->nsfd[LXC_NS_NET] = ret;
+			DEBUG("Preserved net namespace via fd %d", ret);
 		}
-	} else {
-		handler->nsfd[LXC_NS_NET] = ret;
-		DEBUG("Preserved net namespace via fd %d", ret);
-
-		ret = lxc_netns_set_nsid(handler->nsfd[LXC_NS_NET]);
-		if (ret < 0)
-			SYSWARN("Failed to allocate new network namespace id");
-		else
-			TRACE("Allocated new network namespace id");
 	}
+	ret = lxc_netns_set_nsid(handler->nsfd[LXC_NS_NET]);
+	if (ret < 0)
+		SYSWARN("Failed to allocate new network namespace id");
+	else
+		TRACE("Allocated new network namespace id");
 
 	/* Create the network configuration. */
 	if (handler->ns_clone_flags & CLONE_NEWNET) {


More information about the lxc-devel mailing list