Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / x86_64 / ia32 / ia32_aout.c
index fe6bae2..7aac2ca 100644 (file)
 #include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/user32.h>
+#include <asm/ia32.h>
 
 #undef WARN_OLD
 #undef CORE_DUMP /* probably broken */
 
-extern int ia32_setup_arg_pages(struct linux_binprm *bprm, int exec_stack);
-
 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
 static int load_aout_library(struct file*);
 
-#if CORE_DUMP
+#ifdef CORE_DUMP
 static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
 
 /*
@@ -102,7 +101,7 @@ static struct linux_binfmt aout_format = {
        .module         = THIS_MODULE,
        .load_binary    = load_aout_binary,
        .load_shlib     = load_aout_library,
-#if CORE_DUMP
+#ifdef CORE_DUMP
        .core_dump      = aout_core_dump,
 #endif
        .min_coredump   = PAGE_SIZE
@@ -114,10 +113,12 @@ static void set_brk(unsigned long start, unsigned long end)
        end = PAGE_ALIGN(end);
        if (end <= start)
                return;
+       down_write(&current->mm->mmap_sem);
        do_brk(start, end - start);
+       up_write(&current->mm->mmap_sem);
 }
 
-#if CORE_DUMP
+#ifdef CORE_DUMP
 /*
  * These are the only things you should do on a core-file: use only these
  * macros to write out all the necessary info.
@@ -169,19 +170,19 @@ 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 */
        set_fs(USER_DS);
-       if (verify_area(VERIFY_READ, (void *) (unsigned long)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
+       if (!access_ok(VERIFY_READ, (void *) (unsigned long)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
                dump.u_dsize = 0;
-       if (verify_area(VERIFY_READ, (void *) (unsigned long)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
+       if (!access_ok(VERIFY_READ, (void *) (unsigned long)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
                dump.u_ssize = 0;
 
        set_fs(KERNEL_DS);
@@ -282,7 +283,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)
@@ -309,9 +310,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        current->mm->brk = ex.a_bss +
                (current->mm->start_brk = N_BSSADDR(ex));
        current->mm->free_area_cache = TASK_UNMAPPED_BASE;
+       current->mm->cached_hole_size = 0;
 
-       // current->mm->rss = 0;
-       vx_rsspages_sub(current->mm, current->mm->rss);
        current->mm->mmap = NULL;
        compute_creds(bprm);
        current->flags &= ~PF_FORKNOEXEC;
@@ -325,7 +325,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(&current->mm->mmap_sem);
                error = do_brk(text_addr & PAGE_MASK, map_size);
+               up_write(&current->mm->mmap_sem);
+
                if (error != (text_addr & PAGE_MASK)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
@@ -361,7 +364,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(&current->mm->mmap_sem);
                        do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+                       up_write(&current->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),
@@ -398,7 +403,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); 
@@ -469,8 +474,9 @@ static int load_aout_library(struct file *file)
                        error_time = jiffies;
                }
 #endif
-
+               down_write(&current->mm->mmap_sem);
                do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+               up_write(&current->mm->mmap_sem);
                
                file->f_op->read(file, (char *)start_addr,
                        ex.a_text + ex.a_data, &pos);
@@ -494,7 +500,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(&current->mm->mmap_sem);
                error = do_brk(start_addr + len, bss - len);
+               up_write(&current->mm->mmap_sem);
                retval = error;
                if (error != start_addr + len)
                        goto out;