diff options
author | Oleg Nesterov <oleg@redhat.com> | 2013-09-11 17:24:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-11 18:59:09 -0400 |
commit | 6b3c538f5b2cfc53cb6803ec5001bbcf8f18a98e (patch) | |
tree | 5a3dd78b655c93d7248facb2377be2630435b1fc /fs/exec.c | |
parent | 4e0621a07ea58a0dc15859be3b743bdeb194a51b (diff) |
exec: cleanup the error handling in search_binary_handler()
The error hanling and ret-from-loop look confusing and inconsistent.
- "retval >= 0" simply returns
- "!bprm->file" returns too but with read_unlock() because
binfmt_lock was already re-acquired
- "retval != -ENOEXEC || bprm->mm == NULL" does "break" and
relies on the same check after the main loop
Consolidate these checks into a single if/return statement.
need_retry still checks "retval == -ENOEXEC", but this and -ENOENT before
the main loop are not needed. This is only for pathological and
impossible list_empty(&formats) case.
It is not clear why do we check "bprm->mm == NULL", probably this
should be removed.
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/exec.c')
-rw-r--r-- | fs/exec.c | 11 |
1 files changed, 3 insertions, 8 deletions
@@ -1399,22 +1399,17 @@ int search_binary_handler(struct linux_binprm *bprm) | |||
1399 | bprm->recursion_depth++; | 1399 | bprm->recursion_depth++; |
1400 | retval = fmt->load_binary(bprm); | 1400 | retval = fmt->load_binary(bprm); |
1401 | bprm->recursion_depth--; | 1401 | bprm->recursion_depth--; |
1402 | if (retval >= 0) { | 1402 | if (retval >= 0 || retval != -ENOEXEC || |
1403 | bprm->mm == NULL || bprm->file == NULL) { | ||
1403 | put_binfmt(fmt); | 1404 | put_binfmt(fmt); |
1404 | return retval; | 1405 | return retval; |
1405 | } | 1406 | } |
1406 | read_lock(&binfmt_lock); | 1407 | read_lock(&binfmt_lock); |
1407 | put_binfmt(fmt); | 1408 | put_binfmt(fmt); |
1408 | if (retval != -ENOEXEC || bprm->mm == NULL) | ||
1409 | break; | ||
1410 | if (!bprm->file) { | ||
1411 | read_unlock(&binfmt_lock); | ||
1412 | return retval; | ||
1413 | } | ||
1414 | } | 1409 | } |
1415 | read_unlock(&binfmt_lock); | 1410 | read_unlock(&binfmt_lock); |
1416 | 1411 | ||
1417 | if (need_retry && retval == -ENOEXEC && bprm->mm) { | 1412 | if (need_retry && retval == -ENOEXEC) { |
1418 | if (printable(bprm->buf[0]) && printable(bprm->buf[1]) && | 1413 | if (printable(bprm->buf[0]) && printable(bprm->buf[1]) && |
1419 | printable(bprm->buf[2]) && printable(bprm->buf[3])) | 1414 | printable(bprm->buf[2]) && printable(bprm->buf[3])) |
1420 | return retval; | 1415 | return retval; |