Revert "kmod: fix race in usermodehelper code"

This reverts commit c02e3f361c7 ("kmod: fix race in usermodehelper code")

The patch is wrong. UMH_WAIT_EXEC is called with VFORK what ensures
that the child finishes prior returing back to the parent. No race.

In fact, the patch makes it even worse because it does the thing it
claims not do:

- It calls ->complete() on UMH_WAIT_EXEC

- the complete() callback may de-allocated subinfo as seen in the
following call chain:

[<c009f904>] (__link_path_walk+0x20/0xeb4) from [<c00a094c>] (path_walk+0x48/0x94)
[<c00a094c>] (path_walk+0x48/0x94) from [<c00a0a34>] (do_path_lookup+0x24/0x4c)
[<c00a0a34>] (do_path_lookup+0x24/0x4c) from [<c00a158c>] (do_filp_open+0xa4/0x83c)
[<c00a158c>] (do_filp_open+0xa4/0x83c) from [<c009ba90>] (open_exec+0x24/0xe0)
[<c009ba90>] (open_exec+0x24/0xe0) from [<c009bfa8>] (do_execve+0x7c/0x2e4)
[<c009bfa8>] (do_execve+0x7c/0x2e4) from [<c0026a80>] (kernel_execve+0x34/0x80)
[<c0026a80>] (kernel_execve+0x34/0x80) from [<c004b514>] (____call_usermodehelper+0x130/0x148)
[<c004b514>] (____call_usermodehelper+0x130/0x148) from [<c0024858>] (kernel_thread_exit+0x0/0x8)

and the path pointer was NULL. Good that ARM's kernel_execve()
doesn't check the pointer for NULL or else I wouldn't notice it.

The only race there might be is with UMH_NO_WAIT but it is too late for
me to investigate it now. UMH_WAIT_PROC could probably also use VFORK
and we could save one exec. So the only race I see is with UMH_NO_WAIT
and recent scheduler changes where the child does not always run first
might have trigger here something but as I said, it is late....

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Sebastian Andrzej Siewior and committed by Linus Torvalds 95e0d86b 0dd52d0d

+5 -8
+5 -8
kernel/kmod.c
··· 143 143 static int ____call_usermodehelper(void *data) 144 144 { 145 145 struct subprocess_info *sub_info = data; 146 - enum umh_wait wait = sub_info->wait; 147 146 int retval; 148 147 149 148 BUG_ON(atomic_read(&sub_info->cred->usage) != 1); ··· 184 185 */ 185 186 set_user_nice(current, 0); 186 187 187 - if (wait == UMH_WAIT_EXEC) 188 - complete(sub_info->complete); 189 - 190 188 retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); 191 189 192 190 /* Exec failed? */ 193 - if (wait != UMH_WAIT_EXEC) 194 - sub_info->retval = retval; 191 + sub_info->retval = retval; 195 192 do_exit(0); 196 193 } 197 194 ··· 266 271 267 272 switch (wait) { 268 273 case UMH_NO_WAIT: 269 - case UMH_WAIT_EXEC: 270 274 break; 271 275 272 276 case UMH_WAIT_PROC: 273 277 if (pid > 0) 274 278 break; 275 279 sub_info->retval = pid; 276 - break; 280 + /* FALLTHROUGH */ 281 + 282 + case UMH_WAIT_EXEC: 283 + complete(sub_info->complete); 277 284 } 278 285 } 279 286