aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-05-04 20:11:36 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-10-09 02:39:00 -0400
commit19d860a140beac48a1377f179e693abe86a9dac9 (patch)
tree4da809a162a3b9aea8575828f52e150b26ca6ff1 /fs/exec.c
parent2926620145095ffb0350b2312ac9d0af8537796f (diff)
handle suicide on late failure exits in execve() in search_binary_handler()
... rather than doing that in the guts of ->load_binary(). [updated to fix the bug spotted by Shentino - for SIGSEGV we really need something stronger than send_sig_info(); again, better do that in one place] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/exec.c b/fs/exec.c
index a2b42a98c743..7302b75a9820 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -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;