summaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorhongfeng <hongfeng@marvell.com>2012-10-05 02:12:25 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-05 20:04:48 +0200
commit6c0c0d4d1080840eabb3d055d2fd81911111c5fd (patch)
tree16d86fae708a4ef2a5ed3180391ba0f45b081cda /kernel/sys.c
parentkernel/sys.c: call disable_nonboot_cpus() in kernel_restart() (diff)
downloadlinux-6c0c0d4d1080840eabb3d055d2fd81911111c5fd.tar.xz
linux-6c0c0d4d1080840eabb3d055d2fd81911111c5fd.zip
poweroff: fix bug in orderly_poweroff()
orderly_poweroff is trying to poweroff platform in two steps: step 1: Call user space application to poweroff step 2: If user space poweroff fail, then do a force power off if force param is set. The bug here is, step 1 is always successful with param UMH_NO_WAIT, which obey the design goal of orderly_poweroff. We have two choices here: UMH_WAIT_EXEC which means wait for the exec, but not the process; UMH_WAIT_PROC which means wait for the process to complete. we need to trade off the two choices: If using UMH_WAIT_EXEC, there is potential issue comments by Serge E. Hallyn: The exec will have started, but may for whatever (very unlikely) reason fail. If using UMH_WAIT_PROC, there is potential issue comments by Eric W. Biederman: If the caller is not running in a kernel thread then we can easily get into a case where the user space caller will block waiting for us when we are waiting for the user space caller. Thanks for their excellent ideas, based on the above discussion, we finally choose UMH_WAIT_EXEC, which is much more safe, if the user application really fails, we just complain the application itself, it seems a better choice here. Signed-off-by: Feng Hong <hongfeng@marvell.com> Acked-by: Kees Cook <keescook@chromium.org> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Acked-by: "Rafael J. Wysocki" <rjw@sisk.pl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index fdad206165d0..c5cb5b99cb81 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2205,7 +2205,7 @@ static int __orderly_poweroff(void)
return -ENOMEM;
}
- ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_NO_WAIT,
+ ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_WAIT_EXEC,
NULL, argv_cleanup, NULL);
if (ret == -ENOMEM)
argv_free(argv);