Commit b140f251 authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by Linus Torvalds

Invalid return value of execve() resulting in oopses

When elf loader fails to map executable (due to memory shortage or because
binary is malformed), it can return 0.  Normally, this is invisible because
process is killed with SIGKILL and it never returns to user space.

But if exec() is called from kernel thread (hotplug, whatever)
consequences are more interesting and vary depending on architecture.

i386.   Nothing especially interesting, execve() just returns
        with "success"  :-)

x86_64. Fake zero frame is used on way to caller, RSP/RIP are loaded
        with zeros, ergo... double fault.

ia64.   Similar to i386, but r32...r95 are corrupted. Sometimes it
        oopses due to return to zero PC, sometimes it sees NaT in
        rXX and oopses due to NaT consumption.
Signed-off-by: default avatarAlexey Kuznetsov <alexey@openvz.org>
Signed-off-by: default avatarKirill Korotaev <dev@openvz.org>
Signed-off-by: default avatarPavel Emelianov <xemul@openvz.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ce0be127
...@@ -871,6 +871,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -871,6 +871,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
elf_prot, elf_flags); elf_prot, elf_flags);
if (BAD_ADDR(error)) { if (BAD_ADDR(error)) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
retval = IS_ERR((void *)error) ?
PTR_ERR((void*)error) : -EINVAL;
goto out_free_dentry; goto out_free_dentry;
} }
...@@ -900,6 +902,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -900,6 +902,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
TASK_SIZE - elf_ppnt->p_memsz < k) { TASK_SIZE - elf_ppnt->p_memsz < k) {
/* set_brk can never work. Avoid overflows. */ /* set_brk can never work. Avoid overflows. */
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
retval = -EINVAL;
goto out_free_dentry; goto out_free_dentry;
} }
......
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