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@gmail.com>
This commit is contained in:
Rachid Koucha 2019-06-15 15:17:50 +02:00 committed by GitHub
parent 3d43f6113b
commit aa0c0e7b8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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) {