Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / fs / binfmt_flat.c
index 0bc28fe..a37a000 100644 (file)
@@ -16,7 +16,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -36,6 +35,7 @@
 #include <linux/personality.h>
 #include <linux/init.h>
 #include <linux/flat.h>
+#include <linux/syscalls.h>
 #include <linux/vs_memory.h>
 
 #include <asm/byteorder.h>
@@ -78,8 +78,6 @@ static int load_flat_shared_library(int id, struct lib_info *p);
 static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);
 static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file);
 
-extern void dump_thread(struct pt_regs *, struct user *);
-
 static struct linux_binfmt flat_format = {
        .module         = THIS_MODULE,
        .load_binary    = load_flat_binary,
@@ -429,6 +427,7 @@ static int load_flat_file(struct linux_binprm * bprm,
        int i, rev, relocs = 0;
        loff_t fpos;
        unsigned long start_code, end_code;
+       int ret;
 
        hdr = ((struct flat_hdr *) bprm->buf);          /* exec-header */
        inode = bprm->file->f_dentry->d_inode;
@@ -445,27 +444,33 @@ static int load_flat_file(struct linux_binprm * bprm,
        flags     = ntohl(hdr->flags);
        rev       = ntohl(hdr->rev);
 
-       if (flags & FLAT_FLAG_KTRACE)
-               printk("BINFMT_FLAT: Loading file: %s\n", bprm->filename);
-
-       if (strncmp(hdr->magic, "bFLT", 4) ||
-                       (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION)) {
+       if (strncmp(hdr->magic, "bFLT", 4)) {
                /*
                 * because a lot of people do not manage to produce good
                 * flat binaries,  we leave this printk to help them realise
                 * the problem.  We only print the error if its not a script file
                 */
                if (strncmp(hdr->magic, "#!", 2))
-                       printk("BINFMT_FLAT: bad magic/rev (0x%x, need 0x%x)\n",
-                                       rev, (int) FLAT_VERSION);
-               return -ENOEXEC;
+                       printk("BINFMT_FLAT: bad header magic\n");
+               ret = -ENOEXEC;
+               goto err;
+       }
+
+       if (flags & FLAT_FLAG_KTRACE)
+               printk("BINFMT_FLAT: Loading file: %s\n", bprm->filename);
+
+       if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) {
+               printk("BINFMT_FLAT: bad flat file version 0x%x (supported 0x%x and 0x%x)\n", rev, FLAT_VERSION, OLD_FLAT_VERSION);
+               ret = -ENOEXEC;
+               goto err;
        }
        
        /* Don't allow old format executables to use shared libraries */
        if (rev == OLD_FLAT_VERSION && id != 0) {
                printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n",
                                (int) FLAT_VERSION);
-               return -ENOEXEC;
+               ret = -ENOEXEC;
+               goto err;
        }
 
        /*
@@ -478,7 +483,8 @@ static int load_flat_file(struct linux_binprm * bprm,
 #ifndef CONFIG_BINFMT_ZFLAT
        if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
                printk("Support for ZFLAT executables is not enabled.\n");
-               return -ENOEXEC;
+               ret = -ENOEXEC;
+               goto err;
        }
 #endif
 
@@ -487,20 +493,24 @@ static int load_flat_file(struct linux_binprm * bprm,
         * 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 (data_len + bss_len > rlim)
-               return -ENOMEM;
+       if (data_len + bss_len > rlim) {
+               ret = -ENOMEM;
+               goto err;
+       }
 
        /* Flush all traces of the currently running executable */
        if (id == 0) {
                result = flush_old_exec(bprm);
-               if (result)
-                       return result;
+               if (result) {
+                       ret = result;
+                       goto err;
+               }
 
                /* OK, This is the point of no return */
-               set_personality(PER_LINUX);
+               set_personality(PER_LINUX_32BIT);
        }
 
        /*
@@ -521,19 +531,20 @@ static int load_flat_file(struct linux_binprm * bprm,
                DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
 
                down_write(&current->mm->mmap_sem);
-               textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0);
+               textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_PRIVATE, 0);
                up_write(&current->mm->mmap_sem);
                if (!textpos  || textpos >= (unsigned long) -4096) {
                        if (!textpos)
                                textpos = (unsigned long) -ENOMEM;
                        printk("Unable to mmap process text, errno %d\n", (int)-textpos);
-                       return(textpos);
+                       ret = textpos;
+                       goto err;
                }
 
                down_write(&current->mm->mmap_sem);
                realdatastart = do_mmap(0, 0, data_len + extra +
                                MAX_SHARED_LIBS * sizeof(unsigned long),
-                               PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);
+                               PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
                up_write(&current->mm->mmap_sem);
 
                if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -542,7 +553,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                        printk("Unable to allocate RAM for process data, errno %d\n",
                                        (int)-datapos);
                        do_munmap(current->mm, textpos, text_len);
-                       return realdatastart;
+                       ret = realdatastart;
+                       goto err;
                }
                datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
 
@@ -564,7 +576,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                        printk("Unable to read data+bss, errno %d\n", (int)-result);
                        do_munmap(current->mm, textpos, text_len);
                        do_munmap(current->mm, realdatastart, data_len + extra);
-                       return result;
+                       ret = result;
+                       goto err;
                }
 
                reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
@@ -575,14 +588,15 @@ static int load_flat_file(struct linux_binprm * bprm,
                down_write(&current->mm->mmap_sem);
                textpos = do_mmap(0, 0, text_len + data_len + extra +
                                        MAX_SHARED_LIBS * sizeof(unsigned long),
-                               PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0);
+                               PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
                up_write(&current->mm->mmap_sem);
                if (!textpos  || textpos >= (unsigned long) -4096) {
                        if (!textpos)
                                textpos = (unsigned long) -ENOMEM;
                        printk("Unable to allocate RAM for process text/data, errno %d\n",
                                        (int)-textpos);
-                       return(textpos);
+                       ret = textpos;
+                       goto err;
                }
 
                realdatastart = textpos + ntohl(hdr->data_start);
@@ -627,7 +641,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                        printk("Unable to read code+data+bss, errno %d\n",(int)-result);
                        do_munmap(current->mm, textpos, text_len + data_len + extra +
                                MAX_SHARED_LIBS * sizeof(unsigned long));
-                       return result;
+                       ret = result;
+                       goto err;
                }
        }
 
@@ -651,8 +666,6 @@ static int load_flat_file(struct linux_binprm * bprm,
                current->mm->start_brk = datapos + data_len + bss_len;
                current->mm->brk = (current->mm->start_brk + 3) & ~3;
                current->mm->context.end_brk = memp + ksize((void *) memp) - stack_len;
-               // current->mm->rss = 0;
-               vx_rsspages_sub(current->mm, current->mm->rss);
        }
 
        if (flags & FLAT_FLAG_KTRACE)
@@ -692,8 +705,10 @@ static int load_flat_file(struct linux_binprm * bprm,
                        unsigned long addr;
                        if (*rp) {
                                addr = calc_reloc(*rp, libinfo, id, 0);
-                               if (addr == RELOC_FAILED)
-                                       return -ENOEXEC;
+                               if (addr == RELOC_FAILED) {
+                                       ret = -ENOEXEC;
+                                       goto err;
+                               }
                                *rp = addr;
                        }
                }
@@ -720,8 +735,10 @@ static int load_flat_file(struct linux_binprm * bprm,
                        relval = ntohl(reloc[i]);
                        addr = flat_get_relocate_addr(relval);
                        rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
-                       if (rp == (unsigned long *)RELOC_FAILED)
-                               return -ENOEXEC;
+                       if (rp == (unsigned long *)RELOC_FAILED) {
+                               ret = -ENOEXEC;
+                               goto err;
+                       }
 
                        /* Get the pointer's value.  */
                        addr = flat_get_addr_from_rp(rp, relval, flags);
@@ -733,8 +750,10 @@ static int load_flat_file(struct linux_binprm * bprm,
                                if ((flags & FLAT_FLAG_GOTPIC) == 0)
                                        addr = ntohl(addr);
                                addr = calc_reloc(addr, libinfo, id, 0);
-                               if (addr == RELOC_FAILED)
-                                       return -ENOEXEC;
+                               if (addr == RELOC_FAILED) {
+                                       ret = -ENOEXEC;
+                                       goto err;
+                               }
 
                                /* Write back the relocated pointer.  */
                                flat_put_addr_at_rp(rp, addr, relval);
@@ -754,6 +773,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                        stack_len);
 
        return 0;
+err:
+       return ret;
 }
 
 
@@ -877,9 +898,6 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        
        start_thread(regs, start_addr, current->mm->start_stack);
 
-       if (current->ptrace & PT_PTRACED)
-               send_sig(SIGTRAP, current, 0);
-
        return 0;
 }