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] / fs / binfmt_flat.c
index 07a21b7..4b051ad 100644 (file)
@@ -36,6 +36,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 +79,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 +428,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 +445,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 +484,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
 
@@ -490,14 +497,18 @@ static int load_flat_file(struct linux_binprm * bprm,
        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);
@@ -521,13 +532,14 @@ 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, MAP_SHARED, 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);
@@ -542,7 +554,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 +577,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));
@@ -582,7 +596,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                                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 +642,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,7 +667,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;
-               set_mm_counter(current->mm, rss, 0);
        }
 
        if (flags & FLAT_FLAG_KTRACE)
@@ -691,8 +706,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;
                        }
                }
@@ -719,8 +736,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);
@@ -732,8 +751,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);
@@ -753,6 +774,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                        stack_len);
 
        return 0;
+err:
+       return ret;
 }