summaryrefslogtreecommitdiffstats
path: root/kernel/kmod.c
diff options
context:
space:
mode:
authorNigel Cunningham <nigel@nigel.suspend2.net>2008-01-18 00:21:21 +0100
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-18 00:38:59 +0100
commit784680336b616dcc4c17cbd25add3b49c555cdeb (patch)
treee607ed69188a99590a7708c922500882702b8578 /kernel/kmod.c
parentRevert "local_t Documentation update" (diff)
downloadlinux-784680336b616dcc4c17cbd25add3b49c555cdeb.tar.xz
linux-784680336b616dcc4c17cbd25add3b49c555cdeb.zip
Fix unbalanced helper_lock in kernel/kmod.c
call_usermodehelper_exec() has an exit path that can leave the helper_lock() call at the top of the routine unbalanced. The attached patch fixes this issue. Signed-off-by: Nigel Cunningham <nigel@tuxonice.net> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r--kernel/kmod.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c
index c6a4f8aebeba..bb7df2a28bd7 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -451,13 +451,11 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
enum umh_wait wait)
{
DECLARE_COMPLETION_ONSTACK(done);
- int retval;
+ int retval = 0;
helper_lock();
- if (sub_info->path[0] == '\0') {
- retval = 0;
+ if (sub_info->path[0] == '\0')
goto out;
- }
if (!khelper_wq || usermodehelper_disabled) {
retval = -EBUSY;
@@ -468,13 +466,14 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
sub_info->wait = wait;
queue_work(khelper_wq, &sub_info->work);
- if (wait == UMH_NO_WAIT) /* task has freed sub_info */
- return 0;
+ if (wait == UMH_NO_WAIT) /* task has freed sub_info */
+ goto unlock;
wait_for_completion(&done);
retval = sub_info->retval;
- out:
+out:
call_usermodehelper_freeinfo(sub_info);
+unlock:
helper_unlock();
return retval;
}