diff options
author | Oleg Nesterov <oleg@redhat.com> | 2013-09-11 17:24:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-11 18:59:05 -0400 |
commit | 92eaa565add62d56b90987f58ea9feafc5a7c183 (patch) | |
tree | 78f7bfaa0b99b2b2f5b554bc883b67ac68412e21 /fs | |
parent | 52f14282bb0c3d3e5ba2a9eaacb12ff37a033e7e (diff) |
exec: kill ->load_binary != NULL check in search_binary_handler()
search_binary_handler() checks ->load_binary != NULL for no reason, this
method should be always defined. Turn this check into WARN_ON() and move
it into __register_binfmt().
Also, kill the function pointer. The current code looks confusing, as if
->load_binary can go away after read_unlock(&binfmt_lock). But we rely on
module_get(fmt->module), this fmt can't be changed or unregistered,
otherwise this code is buggy anyway.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Kees Cook <keescook@chromium.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Evgeniy Polyakov <zbr@ioremap.net>
Cc: Zach Levis <zml@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/exec.c | 7 |
1 files changed, 3 insertions, 4 deletions
@@ -74,6 +74,8 @@ static DEFINE_RWLOCK(binfmt_lock); | |||
74 | void __register_binfmt(struct linux_binfmt * fmt, int insert) | 74 | void __register_binfmt(struct linux_binfmt * fmt, int insert) |
75 | { | 75 | { |
76 | BUG_ON(!fmt); | 76 | BUG_ON(!fmt); |
77 | if (WARN_ON(!fmt->load_binary)) | ||
78 | return; | ||
77 | write_lock(&binfmt_lock); | 79 | write_lock(&binfmt_lock); |
78 | insert ? list_add(&fmt->lh, &formats) : | 80 | insert ? list_add(&fmt->lh, &formats) : |
79 | list_add_tail(&fmt->lh, &formats); | 81 | list_add_tail(&fmt->lh, &formats); |
@@ -1389,14 +1391,11 @@ int search_binary_handler(struct linux_binprm *bprm) | |||
1389 | for (try=0; try<2; try++) { | 1391 | for (try=0; try<2; try++) { |
1390 | read_lock(&binfmt_lock); | 1392 | read_lock(&binfmt_lock); |
1391 | list_for_each_entry(fmt, &formats, lh) { | 1393 | list_for_each_entry(fmt, &formats, lh) { |
1392 | int (*fn)(struct linux_binprm *) = fmt->load_binary; | ||
1393 | if (!fn) | ||
1394 | continue; | ||
1395 | if (!try_module_get(fmt->module)) | 1394 | if (!try_module_get(fmt->module)) |
1396 | continue; | 1395 | continue; |
1397 | read_unlock(&binfmt_lock); | 1396 | read_unlock(&binfmt_lock); |
1398 | bprm->recursion_depth++; | 1397 | bprm->recursion_depth++; |
1399 | retval = fn(bprm); | 1398 | retval = fmt->load_binary(bprm); |
1400 | bprm->recursion_depth--; | 1399 | bprm->recursion_depth--; |
1401 | if (retval >= 0) { | 1400 | if (retval >= 0) { |
1402 | put_binfmt(fmt); | 1401 | put_binfmt(fmt); |