X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fbinfmt_aout.c;h=5bef1b5bb1933324ef484c9a26817da3011abd37;hb=8e8ece46a861c84343256819eaec77e608ff9217;hp=40ce9d484f3463e2ed9c6d0588ba678cce65494d;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 40ce9d484..5bef1b5bb 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -28,7 +28,6 @@ #include #include -#include #include static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); @@ -45,13 +44,21 @@ static struct linux_binfmt aout_format = { .min_coredump = PAGE_SIZE }; -static void set_brk(unsigned long start, unsigned long end) +#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) + +static int set_brk(unsigned long start, unsigned long end) { start = PAGE_ALIGN(start); end = PAGE_ALIGN(end); - if (end <= start) - return; - do_brk(start, end - start); + if (end > start) { + unsigned long addr; + down_write(¤t->mm->mmap_sem); + addr = do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); + if (BAD_ADDR(addr)) + return addr; + } + return 0; } /* @@ -109,7 +116,7 @@ static int aout_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)); #ifndef __sparc__ dump.u_ar0 = (void *)(((unsigned long)(&dump.regs)) - ((unsigned long)(&dump))); #endif @@ -120,36 +127,36 @@ static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file) if we wrote the stack, but not the data area. */ #ifdef __sparc__ if ((dump.u_dsize+dump.u_ssize) > - current->rlim[RLIMIT_CORE].rlim_cur) + current->signal->rlim[RLIMIT_CORE].rlim_cur) dump.u_dsize = 0; #else 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; #endif /* Make sure we have enough room to write the stack and data areas. */ #ifdef __sparc__ if ((dump.u_ssize) > - current->rlim[RLIMIT_CORE].rlim_cur) + current->signal->rlim[RLIMIT_CORE].rlim_cur) dump.u_ssize = 0; #else if ((dump.u_ssize+1) * PAGE_SIZE > - current->rlim[RLIMIT_CORE].rlim_cur) + current->signal->rlim[RLIMIT_CORE].rlim_cur) dump.u_ssize = 0; #endif /* make sure we actually have a data and stack area to dump */ set_fs(USER_DS); #ifdef __sparc__ - 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; #else - if (verify_area(VERIFY_READ, (void *) START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) + if (verify_area(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) dump.u_dsize = 0; - if (verify_area(VERIFY_READ, (void *) START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) + if (verify_area(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) dump.u_ssize = 0; #endif @@ -195,17 +202,18 @@ end_coredump: * memory and creates the pointer tables from them, and puts their * addresses on the "stack", returning the new stack pointer value. */ -static unsigned long * create_aout_tables(char * p, struct linux_binprm * bprm) +static unsigned long __user *create_aout_tables(char __user *p, struct linux_binprm * bprm) { - char **argv, **envp; - unsigned long * sp; + char __user * __user *argv; + char __user * __user *envp; + unsigned long __user *sp; int argc = bprm->argc; int envc = bprm->envc; - sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p); + sp = (void __user *)((-(unsigned long)sizeof(char *)) & (unsigned long) p); #ifdef __sparc__ /* This imposes the proper stack alignment for a new process. */ - sp = (unsigned long *) (((unsigned long) sp) & ~7); + sp = (void __user *) (((unsigned long) sp) & ~7); if ((envc+argc+3)&1) --sp; #endif #ifdef __alpha__ @@ -222,9 +230,9 @@ static unsigned long * create_aout_tables(char * p, struct linux_binprm * bprm) put_user(0x3e9, --sp); #endif sp -= envc+1; - envp = (char **) sp; + envp = (char __user * __user *) sp; sp -= argc+1; - argv = (char **) sp; + argv = (char __user * __user *) sp; #if defined(__i386__) || defined(__mc68000__) || defined(__arm__) || defined(__arch_um__) put_user((unsigned long) envp,--sp); put_user((unsigned long) argv,--sp); @@ -279,7 +287,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,9 +316,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) (current->mm->start_data = N_DATADDR(ex)); current->mm->brk = ex.a_bss + (current->mm->start_brk = N_BSSADDR(ex)); - current->mm->free_area_cache = TASK_UNMAPPED_BASE; + current->mm->free_area_cache = current->mm->mmap_base; - // current->mm->rss = 0; vx_rsspages_sub(current->mm, current->mm->rss); current->mm->mmap = NULL; compute_creds(bprm); @@ -320,10 +327,14 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) loff_t pos = fd_offset; /* Fuck me plenty... */ /* */ + down_write(¤t->mm->mmap_sem); error = do_brk(N_TXTADDR(ex), ex.a_text); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex), ex.a_text, &pos); + down_write(¤t->mm->mmap_sem); error = do_brk(N_DATADDR(ex), ex.a_data); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex), ex.a_data, &pos); goto beyond_if; @@ -343,14 +354,16 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) pos = 32; map_size = ex.a_text+ex.a_data; #endif - + 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; } - error = bprm->file->f_op->read(bprm->file, (char *)text_addr, + error = bprm->file->f_op->read(bprm->file, + (char __user *)text_addr, ex.a_text+ex.a_data, &pos); if ((signed long)error < 0) { send_sig(SIGKILL, current, 0); @@ -378,8 +391,11 @@ 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); - 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); flush_icache_range((unsigned long) N_TXTADDR(ex), (unsigned long) N_TXTADDR(ex) + @@ -413,9 +429,13 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) beyond_if: set_binfmt(&aout_format); - set_brk(current->mm->start_brk, current->mm->brk); + retval = set_brk(current->mm->start_brk, current->mm->brk); + if (retval < 0) { + send_sig(SIGKILL, current, 0); + return retval; + } - retval = setup_arg_pages(bprm, EXSTACK_DEFAULT); + retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); if (retval < 0) { /* Someone check-me: is this error path enough? */ send_sig(SIGKILL, current, 0); @@ -423,7 +443,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); #ifdef __alpha__ regs->gp = ex.a_gpvalue; #endif @@ -478,10 +498,11 @@ static int load_aout_library(struct file *file) file->f_dentry->d_name.name); error_time = jiffies; } - + 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, + file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); flush_icache_range((unsigned long) start_addr, (unsigned long) start_addr + ex.a_text + ex.a_data); @@ -503,7 +524,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;