Commit 3ed88a51 authored by Andrew Morton's avatar Andrew Morton Committed by James Bottomley

[PATCH] fix memory leak in load_elf_binary()

- Fix an error-path leak of memory and a dentry in load_elf_binary()
  (spotted by Oleg Drokin).

- Tidy up the handling of bad executable images: return -ENOEXEC rather
  than 0.  (We've committed suicide anyway, so probably nobody gets to see
  this).

- Fix up the logic in load_aout_interp().  It gets itself all set up to
  return -ENOEXEC but there is in fact no path by which it can do this.  Just
  return ~0UL on errors, like load_elf_interp().
parent a54785ce
...@@ -390,7 +390,6 @@ static unsigned long load_aout_interp(struct exec * interp_ex, ...@@ -390,7 +390,6 @@ static unsigned long load_aout_interp(struct exec * interp_ex,
unsigned long text_data, elf_entry = ~0UL; unsigned long text_data, elf_entry = ~0UL;
char * addr; char * addr;
loff_t offset; loff_t offset;
int retval;
current->mm->end_code = interp_ex->a_text; current->mm->end_code = interp_ex->a_text;
text_data = interp_ex->a_text + interp_ex->a_data; text_data = interp_ex->a_text + interp_ex->a_data;
...@@ -412,11 +411,9 @@ static unsigned long load_aout_interp(struct exec * interp_ex, ...@@ -412,11 +411,9 @@ static unsigned long load_aout_interp(struct exec * interp_ex,
} }
do_brk(0, text_data); do_brk(0, text_data);
retval = -ENOEXEC;
if (!interpreter->f_op || !interpreter->f_op->read) if (!interpreter->f_op || !interpreter->f_op->read)
goto out; goto out;
retval = interpreter->f_op->read(interpreter, addr, text_data, &offset); if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
if (retval < 0)
goto out; goto out;
flush_icache_range((unsigned long)addr, flush_icache_range((unsigned long)addr,
(unsigned long)addr + text_data); (unsigned long)addr + text_data);
...@@ -638,7 +635,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -638,7 +635,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
retval = setup_arg_pages(bprm); retval = setup_arg_pages(bprm);
if (retval < 0) { if (retval < 0) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
return retval; goto out_free_dentry;
} }
current->mm->start_stack = bprm->p; current->mm->start_stack = bprm->p;
...@@ -742,7 +739,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -742,7 +739,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
printk(KERN_ERR "Unable to load interpreter\n"); printk(KERN_ERR "Unable to load interpreter\n");
kfree(elf_phdata); kfree(elf_phdata);
send_sig(SIGSEGV, current, 0); send_sig(SIGSEGV, current, 0);
return 0; retval = -ENOEXEC; /* Nobody gets to see this, but.. */
goto out;
} }
} else { } else {
elf_entry = elf_ex.e_entry; elf_entry = elf_ex.e_entry;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment