aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorAndrew Morton <akpm@linux-foundation.org>2012-07-30 17:40:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 20:25:13 -0400
commitb57b44ae698944ffc6161352b8ff5c9cf9c592e2 (patch)
tree15d8d4c9681c2cba7c882f29b1b4f88378928095 /kernel/sys.c
parent45226e944ce071d0231949f2fea90969437cd2dc (diff)
kernel/sys.c: avoid argv_free(NULL)
If argv_split() failed, the code will end up calling argv_free(NULL). Fix it up and clean things up a bit. Addresses Coverity report 703573. Cc: Cyrill Gorcunov <gorcunov@openvz.org> Cc: Kees Cook <keescook@chromium.org> Cc: Serge Hallyn <serge.hallyn@canonical.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: WANG Cong <xiyou.wangcong@gmail.com> Cc: Alan Cox <alan@linux.intel.com> Cc: David Rientjes <rientjes@google.com> 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.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index b04ae0390df3..241507f23eca 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2186,46 +2186,52 @@ static void argv_cleanup(struct subprocess_info *info)
2186 argv_free(info->argv); 2186 argv_free(info->argv);
2187} 2187}
2188 2188
2189/** 2189static int __orderly_poweroff(void)
2190 * orderly_poweroff - Trigger an orderly system poweroff
2191 * @force: force poweroff if command execution fails
2192 *
2193 * This may be called from any context to trigger a system shutdown.
2194 * If the orderly shutdown fails, it will force an immediate shutdown.
2195 */
2196int orderly_poweroff(bool force)
2197{ 2190{
2198 int argc; 2191 int argc;
2199 char **argv = argv_split(GFP_ATOMIC, poweroff_cmd, &argc); 2192 char **argv;
2200 static char *envp[] = { 2193 static char *envp[] = {
2201 "HOME=/", 2194 "HOME=/",
2202 "PATH=/sbin:/bin:/usr/sbin:/usr/bin", 2195 "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
2203 NULL 2196 NULL
2204 }; 2197 };
2205 int ret = -ENOMEM; 2198 int ret;
2206 2199
2200 argv = argv_split(GFP_ATOMIC, poweroff_cmd, &argc);
2207 if (argv == NULL) { 2201 if (argv == NULL) {
2208 printk(KERN_WARNING "%s failed to allocate memory for \"%s\"\n", 2202 printk(KERN_WARNING "%s failed to allocate memory for \"%s\"\n",
2209 __func__, poweroff_cmd); 2203 __func__, poweroff_cmd);
2210 goto out; 2204 return -ENOMEM;
2211 } 2205 }
2212 2206
2213 ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_NO_WAIT, 2207 ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_NO_WAIT,
2214 NULL, argv_cleanup, NULL); 2208 NULL, argv_cleanup, NULL);
2215out:
2216 if (likely(!ret))
2217 return 0;
2218
2219 if (ret == -ENOMEM) 2209 if (ret == -ENOMEM)
2220 argv_free(argv); 2210 argv_free(argv);
2221 2211
2222 if (force) { 2212 return ret;
2213}
2214
2215/**
2216 * orderly_poweroff - Trigger an orderly system poweroff
2217 * @force: force poweroff if command execution fails
2218 *
2219 * This may be called from any context to trigger a system shutdown.
2220 * If the orderly shutdown fails, it will force an immediate shutdown.
2221 */
2222int orderly_poweroff(bool force)
2223{
2224 int ret = __orderly_poweroff();
2225
2226 if (ret && force) {
2223 printk(KERN_WARNING "Failed to start orderly shutdown: " 2227 printk(KERN_WARNING "Failed to start orderly shutdown: "
2224 "forcing the issue\n"); 2228 "forcing the issue\n");
2225 2229
2226 /* I guess this should try to kick off some daemon to 2230 /*
2227 sync and poweroff asap. Or not even bother syncing 2231 * I guess this should try to kick off some daemon to sync and
2228 if we're doing an emergency shutdown? */ 2232 * poweroff asap. Or not even bother syncing if we're doing an
2233 * emergency shutdown?
2234 */
2229 emergency_sync(); 2235 emergency_sync();
2230 kernel_power_off(); 2236 kernel_power_off();
2231 } 2237 }