From 2c37fa03ac935bf5f03d9ae7d7dc61ba4fda151a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 3 Jun 2004 05:54:49 -0700 Subject: [PATCH] sparse: annotate (and comment on) kmod.c user pointer usage Big comment, because it wasn't clear why this cast was valid. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/kmod.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/kernel/kmod.c b/kernel/kmod.c index 10d2e8fc58db2..160aa3d958ad2 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -192,10 +192,20 @@ static int wait_for_helper(void *data) allow_signal(SIGCHLD); pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD); - if (pid < 0) + if (pid < 0) { sub_info->retval = pid; - else - sys_wait4(pid, &sub_info->retval, 0, NULL); + } else { + /* + * Normally it is bogus to call wait4() from in-kernel because + * wait4() wants to write the exit code to a userspace address. + * But wait_for_helper() always runs as keventd, and put_user() + * to a kernel address works OK for kernel threads, due to their + * having an mm_segment_t which spans the entire address space. + * + * Thus the __user pointer cast is valid here. + */ + sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL); + } complete(sub_info->complete); return 0; -- 2.53.0