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>
This commit is contained in:
Al Viro
2014-05-04 20:11:36 -04:00
parent 2926620145
commit 19d860a140
5 changed files with 36 additions and 78 deletions

View File

@@ -256,11 +256,8 @@ static int load_aout_binary(struct linux_binprm * bprm)
(current->mm->start_brk = N_BSSADDR(ex));
retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
if (retval < 0) {
/* Someone check-me: is this error path enough? */
send_sig(SIGKILL, current, 0);
if (retval < 0)
return retval;
}
install_exec_creds(bprm);
@@ -278,17 +275,13 @@ static int load_aout_binary(struct linux_binprm * bprm)
map_size = ex.a_text+ex.a_data;
#endif
error = vm_brk(text_addr & PAGE_MASK, map_size);
if (error != (text_addr & PAGE_MASK)) {
send_sig(SIGKILL, current, 0);
if (error != (text_addr & PAGE_MASK))
return error;
}
error = read_code(bprm->file, text_addr, pos,
ex.a_text+ex.a_data);
if ((signed long)error < 0) {
send_sig(SIGKILL, current, 0);
if ((signed long)error < 0)
return error;
}
} else {
if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
(N_MAGIC(ex) != NMAGIC) && printk_ratelimit())
@@ -315,28 +308,22 @@ static int load_aout_binary(struct linux_binprm * bprm)
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset);
if (error != N_TXTADDR(ex)) {
send_sig(SIGKILL, current, 0);
if (error != N_TXTADDR(ex))
return error;
}
error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset + ex.a_text);
if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0);
if (error != N_DATADDR(ex))
return error;
}
}
beyond_if:
set_binfmt(&aout_format);
retval = set_brk(current->mm->start_brk, current->mm->brk);
if (retval < 0) {
send_sig(SIGKILL, current, 0);
if (retval < 0)
return retval;
}
current->mm->start_stack =
(unsigned long) create_aout_tables((char __user *) bprm->p, bprm);