diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-04 20:11:36 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-10-09 02:39:00 -0400 |
commit | 19d860a140beac48a1377f179e693abe86a9dac9 (patch) | |
tree | 4da809a162a3b9aea8575828f52e150b26ca6ff1 /fs/binfmt_aout.c | |
parent | 2926620145095ffb0350b2312ac9d0af8537796f (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/binfmt_aout.c')
-rw-r--r-- | fs/binfmt_aout.c | 25 |
1 files changed, 6 insertions, 19 deletions
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index ca0ba15a7306..929dec08c348 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -256,11 +256,8 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
256 | (current->mm->start_brk = N_BSSADDR(ex)); | 256 | (current->mm->start_brk = N_BSSADDR(ex)); |
257 | 257 | ||
258 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); | 258 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); |
259 | if (retval < 0) { | 259 | if (retval < 0) |
260 | /* Someone check-me: is this error path enough? */ | ||
261 | send_sig(SIGKILL, current, 0); | ||
262 | return retval; | 260 | return retval; |
263 | } | ||
264 | 261 | ||
265 | install_exec_creds(bprm); | 262 | install_exec_creds(bprm); |
266 | 263 | ||
@@ -278,17 +275,13 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
278 | map_size = ex.a_text+ex.a_data; | 275 | map_size = ex.a_text+ex.a_data; |
279 | #endif | 276 | #endif |
280 | error = vm_brk(text_addr & PAGE_MASK, map_size); | 277 | error = vm_brk(text_addr & PAGE_MASK, map_size); |
281 | if (error != (text_addr & PAGE_MASK)) { | 278 | if (error != (text_addr & PAGE_MASK)) |
282 | send_sig(SIGKILL, current, 0); | ||
283 | return error; | 279 | return error; |
284 | } | ||
285 | 280 | ||
286 | error = read_code(bprm->file, text_addr, pos, | 281 | error = read_code(bprm->file, text_addr, pos, |
287 | ex.a_text+ex.a_data); | 282 | ex.a_text+ex.a_data); |
288 | if ((signed long)error < 0) { | 283 | if ((signed long)error < 0) |
289 | send_sig(SIGKILL, current, 0); | ||
290 | return error; | 284 | return error; |
291 | } | ||
292 | } else { | 285 | } else { |
293 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && | 286 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && |
294 | (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) | 287 | (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) |
@@ -315,28 +308,22 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
315 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, | 308 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, |
316 | fd_offset); | 309 | fd_offset); |
317 | 310 | ||
318 | if (error != N_TXTADDR(ex)) { | 311 | if (error != N_TXTADDR(ex)) |
319 | send_sig(SIGKILL, current, 0); | ||
320 | return error; | 312 | return error; |
321 | } | ||
322 | 313 | ||
323 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, | 314 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, |
324 | PROT_READ | PROT_WRITE | PROT_EXEC, | 315 | PROT_READ | PROT_WRITE | PROT_EXEC, |
325 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, | 316 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, |
326 | fd_offset + ex.a_text); | 317 | fd_offset + ex.a_text); |
327 | if (error != N_DATADDR(ex)) { | 318 | if (error != N_DATADDR(ex)) |
328 | send_sig(SIGKILL, current, 0); | ||
329 | return error; | 319 | return error; |
330 | } | ||
331 | } | 320 | } |
332 | beyond_if: | 321 | beyond_if: |
333 | set_binfmt(&aout_format); | 322 | set_binfmt(&aout_format); |
334 | 323 | ||
335 | retval = set_brk(current->mm->start_brk, current->mm->brk); | 324 | retval = set_brk(current->mm->start_brk, current->mm->brk); |
336 | if (retval < 0) { | 325 | if (retval < 0) |
337 | send_sig(SIGKILL, current, 0); | ||
338 | return retval; | 326 | return retval; |
339 | } | ||
340 | 327 | ||
341 | current->mm->start_stack = | 328 | current->mm->start_stack = |
342 | (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); | 329 | (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); |