[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1335604790.5995.22.camel@marge.simpson.net>
Date: Sat, 28 Apr 2012 11:19:50 +0200
From: Mike Galbraith <efault@....de>
To: LKML <linux-kernel@...r.kernel.org>
Cc: Oleg Nesterov <oleg@...hat.com>
Subject: [RFC PATCH] namespaces: fix leak on fork() failure
Greetings,
The attached testcase induces quite a bit of pid/mnt namespace leakage.
The below fixes up one of these leaks. There's still at least one pid
namespace leak left, that being the final put_pid() in softirq context
goes missing.
A trace of the leak that's left shows...
vsftpd-5055 [003] .... 3921.490806: proc_set_super: get_pid_ns: 0xffff8801c996e988 count:1->2
vsftpd-5055 [003] .... 3921.490823: alloc_pid: get_pid_ns: 0xffff8801c996e988 count:2->3
vsftpd-5102 [003] .... 3921.502565: switch_task_namespaces: exiting: 0xffff8801c996e988 count:3
vsftpd-5102 [003] .... 3921.522296: free_nsproxy: put_pid_ns: 0xffff8801c996e988 count:3->2
vsftpd-5055 [003] .... 3921.574201: proc_kill_sb: put_pid_ns: 0xffff8801c996e988 count:2->1
..but that should be..
vsftpd-5055 [003] .... 3921.497313: proc_set_super: get_pid_ns: 0xffff8801c6e65ff0 count:1->2
vsftpd-5055 [003] .... 3921.497330: alloc_pid: get_pid_ns: 0xffff8801c6e65ff0 count:2->3
vsftpd-5124 [003] .... 3921.502977: switch_task_namespaces: exiting: 0xffff8801c6e65ff0 count:3
vsftpd-5124 [003] .... 3921.522308: free_nsproxy: put_pid_ns: 0xffff8801c6e65ff0 count:3->2
vsftpd-5055 [003] .... 3921.698349: proc_kill_sb: put_pid_ns: 0xffff8801c6e65ff0 count:2->1
ksoftirqd/3-16 [003] ..s. 3921.702182: put_pid: put_pid_ns: 0xffff8801c6e65ff0 count:1->0
Anyway, here's what I did for one of the little buggers.
SIGCHLD delivery during fork() may cause failure, resulting in the aborted
child being cloned with CLONE_NEWPID leaking namespaces due to proc being
mounted during pid namespace creation, but not unmounted on fork() failure.
Call pid_ns_release_proc() to prevent the leaks.
Signed-off-by: Mike Galbraith <efault@....de>
kernel/nsproxy.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index b576f7f..fd751d3 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -216,6 +216,14 @@ void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
rcu_assign_pointer(p->nsproxy, new);
if (ns && atomic_dec_and_test(&ns->count)) {
+ /* Handle fork() failure, unmount proc before proceeding */
+ if (unlikely(!new && !((p->flags & PF_EXITING)))) {
+ struct pid_namespace *pid_ns = ns->pid_ns;
+
+ if (pid_ns && pid_ns != &init_pid_ns)
+ pid_ns_release_proc(pid_ns);
+ }
+
/*
* wait for others to get what they want from this nsproxy.
*
View attachment "vsftpd.c" of type "text/x-csrc" (2182 bytes)
Powered by blists - more mailing lists