From: Chris Wright <chrisw@osdl.org>

Anything wrong with just setting a SIG_DFL handler?  W.R.T. the kernel
pointer, either Andrew's patch which does put_user/__put_user depending
on context, or some ugly set_fs() should work.  This simplistic approach
works for me, thoughts?

The wait_for_helper thread needs its own sighand struct, so that it's not
stomping on it's parent's SIGCHLD handler (which is intended to be SIG_IGN). 
This is to make the parent keventd thread properly reaps children.



 25-akpm/kernel/kmod.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

diff -puN kernel/kmod.c~call_usermodehelper-retval-fix-3 kernel/kmod.c
--- 25/kernel/kmod.c~call_usermodehelper-retval-fix-3	Mon Oct  6 05:49:27 2003
+++ 25-akpm/kernel/kmod.c	Mon Oct  6 05:49:27 2003
@@ -185,14 +185,19 @@ static int wait_for_helper(void *data)
 
 	sub_info->retval = 0;
 	pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
-	if (pid < 0)
+	if (pid < 0) {
 		sub_info->retval = pid;
-	else
+	} else {
 		/* We don't have a SIGCHLD signal handler, so this
 		 * always returns -ECHILD, but the important thing is
 		 * that it blocks. */
-		sys_wait4(pid, NULL, 0, NULL);
+		mm_segment_t fs;
 
+		fs = get_fs();
+		set_fs(KERNEL_DS);
+		sys_wait4(pid, &sub_info->retval, 0, NULL);
+		set_fs(fs);
+	}
 	complete(sub_info->complete);
 	return 0;
 }
@@ -210,7 +215,7 @@ static void __call_usermodehelper(void *
 	 * until that is done.  */
 	if (sub_info->wait)
 		pid = kernel_thread(wait_for_helper, sub_info,
-				    CLONE_KERNEL | SIGCHLD);
+				    CLONE_FS | CLONE_FILES | SIGCHLD);
 	else
 		pid = kernel_thread(____call_usermodehelper, sub_info,
 				    CLONE_VFORK | SIGCHLD);

_