Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit eedeb78

Browse files
author
Peter Zijlstra
committed
freezer,umh: Fix call_usermode_helper_exec() vs SIGKILL
Tetsuo-San noted that commit f5d39b0 ("freezer,sched: Rewrite core freezer logic") broke call_usermodehelper_exec() for the KILLABLE case. Specifically it was missed that the second, unconditional, wait_for_completion() was not optional and ensures the on-stack completion is unused before going out-of-scope. Fixes: f5d39b0 ("freezer,sched: Rewrite core freezer logic") Reported-by: [email protected] Reported-by: Tetsuo Handa <[email protected]> Debugged-by: Tetsuo Handa <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent ceaa837 commit eedeb78

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

kernel/umh.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,21 +438,27 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
438438
if (wait == UMH_NO_WAIT) /* task has freed sub_info */
439439
goto unlock;
440440

441-
if (wait & UMH_KILLABLE)
442-
state |= TASK_KILLABLE;
443-
444441
if (wait & UMH_FREEZABLE)
445442
state |= TASK_FREEZABLE;
446443

447-
retval = wait_for_completion_state(&done, state);
448-
if (!retval)
449-
goto wait_done;
450-
451444
if (wait & UMH_KILLABLE) {
445+
retval = wait_for_completion_state(&done, state | TASK_KILLABLE);
446+
if (!retval)
447+
goto wait_done;
448+
452449
/* umh_complete() will see NULL and free sub_info */
453450
if (xchg(&sub_info->complete, NULL))
454451
goto unlock;
452+
453+
/*
454+
* fallthrough; in case of -ERESTARTSYS now do uninterruptible
455+
* wait_for_completion_state(). Since umh_complete() shall call
456+
* complete() in a moment if xchg() above returned NULL, this
457+
* uninterruptible wait_for_completion_state() will not block
458+
* SIGKILL'ed processes for long.
459+
*/
455460
}
461+
wait_for_completion_state(&done, state);
456462

457463
wait_done:
458464
retval = sub_info->retval;

0 commit comments

Comments
 (0)