X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fx86_64%2Fia32%2Fia32_aout.c;h=4fecd6795f81916be8dc74257e643d8d746092d2;hb=8e8ece46a861c84343256819eaec77e608ff9217;hp=040adf6991a22b0c303e8e9b246751779cf50934;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c index 040adf699..4fecd6795 100644 --- a/arch/x86_64/ia32/ia32_aout.c +++ b/arch/x86_64/ia32/ia32_aout.c @@ -25,17 +25,20 @@ #include #include #include +#include #include #include #include #include #include +#include #undef WARN_OLD #undef CORE_DUMP /* probably broken */ -extern int ia32_setup_arg_pages(struct linux_binprm *bprm, int exec_stack); +extern int ia32_setup_arg_pages(struct linux_binprm *bprm, + unsigned long stack_top, int exec_stack); static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); static int load_aout_library(struct file*); @@ -113,7 +116,9 @@ static void set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end <= start) return; + down_write(¤t->mm->mmap_sem); do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); } #if CORE_DUMP @@ -168,12 +173,12 @@ static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file) /* If the size of the dump file exceeds the rlimit, then see what would happen if we wrote the stack, but not the data area. */ if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE > - current->rlim[RLIMIT_CORE].rlim_cur) + current->signal->rlim[RLIMIT_CORE].rlim_cur) dump.u_dsize = 0; /* Make sure we have enough room to write the stack and data areas. */ if ((dump.u_ssize+1) * PAGE_SIZE > - current->rlim[RLIMIT_CORE].rlim_cur) + current->signal->rlim[RLIMIT_CORE].rlim_cur) dump.u_ssize = 0; /* make sure we actually have a data and stack area to dump */ @@ -216,18 +221,19 @@ end_coredump: * memory and creates the pointer tables from them, and puts their * addresses on the "stack", returning the new stack pointer value. */ -static u32 * create_aout_tables(char * p, struct linux_binprm * bprm) +static u32 __user *create_aout_tables(char __user *p, struct linux_binprm *bprm) { - u32 *argv, *envp; - u32 * sp; + u32 __user *argv; + u32 __user *envp; + u32 __user *sp; int argc = bprm->argc; int envc = bprm->envc; - sp = (u32 *) ((-(unsigned long)sizeof(u32)) & (unsigned long) p); + sp = (u32 __user *) ((-(unsigned long)sizeof(u32)) & (unsigned long) p); sp -= envc+1; - envp = (u32 *) sp; + envp = sp; sp -= argc+1; - argv = (u32 *) sp; + argv = sp; put_user((unsigned long) envp,--sp); put_user((unsigned long) argv,--sp); put_user(argc,--sp); @@ -280,7 +286,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) * size limits imposed on them by creating programs with large * arrays in the data or bss. */ - rlim = current->rlim[RLIMIT_DATA].rlim_cur; + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; if (ex.a_data + ex.a_bss > rlim) @@ -308,7 +314,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) (current->mm->start_brk = N_BSSADDR(ex)); current->mm->free_area_cache = TASK_UNMAPPED_BASE; - current->mm->rss = 0; + vx_rsspages_sub(current->mm, current->mm->rss); current->mm->mmap = NULL; compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; @@ -322,7 +328,10 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) pos = 32; map_size = ex.a_text+ex.a_data; + down_write(¤t->mm->mmap_sem); error = do_brk(text_addr & PAGE_MASK, map_size); + up_write(¤t->mm->mmap_sem); + if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); return error; @@ -358,7 +367,9 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { loff_t pos = fd_offset; + down_write(¤t->mm->mmap_sem); do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); flush_icache_range((unsigned long) N_TXTADDR(ex), @@ -395,7 +406,7 @@ beyond_if: set_brk(current->mm->start_brk, current->mm->brk); - retval = ia32_setup_arg_pages(bprm, EXSTACK_DEFAULT); + retval = ia32_setup_arg_pages(bprm, IA32_STACK_TOP, EXSTACK_DEFAULT); if (retval < 0) { /* Someone check-me: is this error path enough? */ send_sig(SIGKILL, current, 0); @@ -403,7 +414,7 @@ beyond_if: } current->mm->start_stack = - (unsigned long) create_aout_tables((char *) bprm->p, bprm); + (unsigned long)create_aout_tables((char __user *)bprm->p, bprm); /* start thread */ asm volatile("movl %0,%%fs" :: "r" (0)); \ asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); @@ -466,8 +477,9 @@ static int load_aout_library(struct file *file) error_time = jiffies; } #endif - + down_write(¤t->mm->mmap_sem); do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + up_write(¤t->mm->mmap_sem); file->f_op->read(file, (char *)start_addr, ex.a_text + ex.a_data, &pos); @@ -491,7 +503,9 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { + down_write(¤t->mm->mmap_sem); error = do_brk(start_addr + len, bss - len); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr + len) goto out;