aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kmod.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2015-10-22 16:32:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-10-23 04:55:10 -0400
commit5211613978cb7353a3237e4372958c0e7514683f (patch)
tree01fae404b1b576e032245ef68ee50f0a92ea8090 /kernel/kmod.c
parent8a70dd2669200ce83255ed8c5ebef7e59f9e8707 (diff)
kmod: don't run async usermode helper as a child of kworker thread
call_usermodehelper_exec_sync() does fork() + wait() with "unignored" SIGCHLD. What we have missed is that this worker thread can have other children previously forked by call_usermodehelper_exec_work() without UMH_WAIT_PROC. If such a child exits in between it becomes a zombie because auto-reaping only works if SIGCHLD is ignored, and nobody can reap it (unless/until this worker thread exits too). Change the !UMH_WAIT_PROC case to use CLONE_PARENT. Note: this is only first step. All PF_KTHREAD tasks, even created by kernel_thread() should have ->parent == kthreadd by default. Fixes: bb304a5c6fc63d8506c ("kmod: handle UMH_WAIT_PROC from system unbound workqueue") Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Rik van Riel <riel@redhat.com> Cc: Christoph Lameter <cl@linux.com> Cc: Tejun Heo <tj@kernel.org> Cc: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r--kernel/kmod.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c
index da98d0593de2..0277d1216f80 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -327,9 +327,13 @@ static void call_usermodehelper_exec_work(struct work_struct *work)
327 call_usermodehelper_exec_sync(sub_info); 327 call_usermodehelper_exec_sync(sub_info);
328 } else { 328 } else {
329 pid_t pid; 329 pid_t pid;
330 330 /*
331 * Use CLONE_PARENT to reparent it to kthreadd; we do not
332 * want to pollute current->children, and we need a parent
333 * that always ignores SIGCHLD to ensure auto-reaping.
334 */
331 pid = kernel_thread(call_usermodehelper_exec_async, sub_info, 335 pid = kernel_thread(call_usermodehelper_exec_async, sub_info,
332 SIGCHLD); 336 CLONE_PARENT | SIGCHLD);
333 if (pid < 0) { 337 if (pid < 0) {
334 sub_info->retval = pid; 338 sub_info->retval = pid;
335 umh_complete(sub_info); 339 umh_complete(sub_info);