X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc64%2Fkernel%2Fbinfmt_aout32.c;h=a68c04e02638f3a2d022ec568f0abe2dcfd3e2b6;hb=8e8ece46a861c84343256819eaec77e608ff9217;hp=4ba5d4801baec35f5c2bdde622f62fdcb76b23fd;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index 4ba5d4801..a68c04e02 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -49,7 +50,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); } /* @@ -95,26 +98,26 @@ static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file) set_fs(KERNEL_DS); has_dumped = 1; current->flags |= PF_DUMPCORE; - strncpy(dump.u_comm, current->comm, sizeof(current->comm)); + strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); dump.signal = signr; dump_thread(regs, &dump); /* 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) > - 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) > - 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 */ set_fs(USER_DS); - if (verify_area(VERIFY_READ, (void *) START_DATA(dump), dump.u_dsize)) + if (verify_area(VERIFY_READ, (void __user *) START_DATA(dump), dump.u_dsize)) dump.u_dsize = 0; - if (verify_area(VERIFY_READ, (void *) START_STACK(dump), dump.u_ssize)) + if (verify_area(VERIFY_READ, (void __user *) START_STACK(dump), dump.u_ssize)) dump.u_ssize = 0; set_fs(KERNEL_DS); @@ -147,31 +150,31 @@ end_coredump: * memory and creates the pointer tables from them, and puts their * addresses on the "stack", returning the new stack pointer value. */ -#define A(__x) ((unsigned long)(__x)) -static u32 *create_aout32_tables(char * p, struct linux_binprm * bprm) +static u32 __user *create_aout32_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(char *)) & (unsigned long) p); + sp = (u32 __user *)((-(unsigned long)sizeof(char *))&(unsigned long)p); /* This imposes the proper stack alignment for a new process. */ - sp = (u32 *) (((unsigned long) sp) & ~7); + sp = (u32 __user *) (((unsigned long) sp) & ~7); if ((envc+argc+3)&1) --sp; sp -= envc+1; - envp = (u32 *) sp; + envp = sp; sp -= argc+1; - argv = (u32 *) sp; + argv = sp; put_user(argc,--sp); current->mm->arg_start = (unsigned long) p; while (argc-->0) { char c; - put_user(((u32)A(p)),argv++); + put_user(((u32)(unsigned long)(p)),argv++); do { get_user(c,p++); } while (c); @@ -180,7 +183,7 @@ static u32 *create_aout32_tables(char * p, struct linux_binprm * bprm) current->mm->arg_end = current->mm->env_start = (unsigned long) p; while (envc-->0) { char c; - put_user(((u32)A(p)),envp++); + put_user(((u32)(unsigned long)(p)),envp++); do { get_user(c,p++); } while (c); @@ -218,7 +221,7 @@ static int load_aout32_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) @@ -239,27 +242,33 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs) current->mm->brk = ex.a_bss + (current->mm->start_brk = N_BSSADDR(ex)); - current->mm->rss = 0; + vx_rsspages_sub(current->mm, current->mm->rss); current->mm->mmap = NULL; compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; if (N_MAGIC(ex) == NMAGIC) { loff_t pos = fd_offset; /* Fuck me plenty... */ + down_write(¤t->mm->mmap_sem); error = do_brk(N_TXTADDR(ex), ex.a_text); - bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex), + up_write(¤t->mm->mmap_sem); + bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text, &pos); + down_write(¤t->mm->mmap_sem); error = do_brk(N_DATADDR(ex), ex.a_data); - bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex), + up_write(¤t->mm->mmap_sem); + bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex), ex.a_data, &pos); goto beyond_if; } if (N_MAGIC(ex) == OMAGIC) { loff_t pos = fd_offset; + down_write(¤t->mm->mmap_sem); do_brk(N_TXTADDR(ex) & PAGE_MASK, ex.a_text+ex.a_data + PAGE_SIZE - 1); - bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex), + up_write(¤t->mm->mmap_sem); + bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); } else { static unsigned long error_time; @@ -272,8 +281,11 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (!bprm->file->f_op->mmap) { loff_t pos = fd_offset; + down_write(¤t->mm->mmap_sem); do_brk(0, ex.a_text+ex.a_data); - bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex), + up_write(¤t->mm->mmap_sem); + bprm->file->f_op->read(bprm->file, + (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); goto beyond_if; } @@ -310,7 +322,7 @@ beyond_if: orig_thr_flags = current_thread_info()->flags; current_thread_info()->flags |= _TIF_32BIT; - retval = setup_arg_pages(bprm, EXSTACK_DEFAULT); + retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); if (retval < 0) { current_thread_info()->flags = orig_thr_flags; @@ -320,11 +332,10 @@ beyond_if: } current->mm->start_stack = - (unsigned long) create_aout32_tables((char *)bprm->p, bprm); + (unsigned long) create_aout32_tables((char __user *)bprm->p, bprm); if (!(orig_thr_flags & _TIF_32BIT)) { - unsigned long pgd_cache; + unsigned long pgd_cache = get_pgd_cache(current->mm->pgd); - pgd_cache = ((unsigned long)current->mm->pgd[0])<<11UL; __asm__ __volatile__("stxa\t%0, [%1] %2\n\t" "membar #Sync" : /* no outputs */ @@ -388,7 +399,9 @@ static int load_aout32_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;