diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 17 |
1 files changed, 11 insertions, 6 deletions
@@ -1372,18 +1372,23 @@ int search_binary_handler(struct linux_binprm *bprm) | |||
1372 | read_unlock(&binfmt_lock); | 1372 | read_unlock(&binfmt_lock); |
1373 | bprm->recursion_depth++; | 1373 | bprm->recursion_depth++; |
1374 | retval = fmt->load_binary(bprm); | 1374 | retval = fmt->load_binary(bprm); |
1375 | read_lock(&binfmt_lock); | ||
1376 | put_binfmt(fmt); | ||
1375 | bprm->recursion_depth--; | 1377 | bprm->recursion_depth--; |
1376 | if (retval >= 0 || retval != -ENOEXEC || | 1378 | if (retval < 0 && !bprm->mm) { |
1377 | bprm->mm == NULL || bprm->file == NULL) { | 1379 | /* we got to flush_old_exec() and failed after it */ |
1378 | put_binfmt(fmt); | 1380 | read_unlock(&binfmt_lock); |
1381 | force_sigsegv(SIGSEGV, current); | ||
1382 | return retval; | ||
1383 | } | ||
1384 | if (retval != -ENOEXEC || !bprm->file) { | ||
1385 | read_unlock(&binfmt_lock); | ||
1379 | return retval; | 1386 | return retval; |
1380 | } | 1387 | } |
1381 | read_lock(&binfmt_lock); | ||
1382 | put_binfmt(fmt); | ||
1383 | } | 1388 | } |
1384 | read_unlock(&binfmt_lock); | 1389 | read_unlock(&binfmt_lock); |
1385 | 1390 | ||
1386 | if (need_retry && retval == -ENOEXEC) { | 1391 | if (need_retry) { |
1387 | if (printable(bprm->buf[0]) && printable(bprm->buf[1]) && | 1392 | if (printable(bprm->buf[0]) && printable(bprm->buf[1]) && |
1388 | printable(bprm->buf[2]) && printable(bprm->buf[3])) | 1393 | printable(bprm->buf[2]) && printable(bprm->buf[3])) |
1389 | return retval; | 1394 | return retval; |