nfsd: nfsd should drop CAP_MKNOD for non-root
[safe/jmp/linux-2.6] / fs / binfmt_flat.c
index 56372ec..5cebf0b 100644 (file)
@@ -229,13 +229,13 @@ static int decompress_exec(
        ret = 10;
        if (buf[3] & EXTRA_FIELD) {
                ret += 2 + buf[10] + (buf[11] << 8);
-               if (unlikely(LBUFSIZE == ret)) {
+               if (unlikely(LBUFSIZE <= ret)) {
                        DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n");
                        goto out_free_buf;
                }
        }
        if (buf[3] & ORIG_NAME) {
-               for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
+               while (ret < LBUFSIZE && buf[ret++] != 0)
                        ;
                if (unlikely(LBUFSIZE == ret)) {
                        DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n");
@@ -243,7 +243,7 @@ static int decompress_exec(
                }
        }
        if (buf[3] & COMMENT) {
-               for (;  ret < LBUFSIZE && (buf[ret] != 0); ret++)
+               while (ret < LBUFSIZE && buf[ret++] != 0)
                        ;
                if (unlikely(LBUFSIZE == ret)) {
                        DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n");
@@ -417,8 +417,8 @@ static int load_flat_file(struct linux_binprm * bprm,
        unsigned long textpos = 0, datapos = 0, result;
        unsigned long realdatastart = 0;
        unsigned long text_len, data_len, bss_len, stack_len, flags;
-       unsigned long len, reallen, memp = 0;
-       unsigned long extra, rlim;
+       unsigned long len, memp = 0;
+       unsigned long memp_size, extra, rlim;
        unsigned long *reloc = 0, *rp;
        struct inode *inode;
        int i, rev, relocs = 0;
@@ -543,17 +543,10 @@ static int load_flat_file(struct linux_binprm * bprm,
                }
 
                len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
+               len = PAGE_ALIGN(len);
                down_write(&current->mm->mmap_sem);
                realdatastart = do_mmap(0, 0, len,
                        PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
-               /* Remap to use all availabe slack region space */
-               if (realdatastart && (realdatastart < (unsigned long)-4096)) {
-                       reallen = kobjsize((void *)realdatastart);
-                       if (reallen > len) {
-                               realdatastart = do_mremap(realdatastart, len,
-                                       reallen, MREMAP_FIXED, realdatastart);
-                       }
-               }
                up_write(&current->mm->mmap_sem);
 
                if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -591,21 +584,14 @@ static int load_flat_file(struct linux_binprm * bprm,
 
                reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
                memp = realdatastart;
-
+               memp_size = len;
        } else {
 
                len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
+               len = PAGE_ALIGN(len);
                down_write(&current->mm->mmap_sem);
                textpos = do_mmap(0, 0, len,
                        PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
-               /* Remap to use all availabe slack region space */
-               if (textpos && (textpos < (unsigned long) -4096)) {
-                       reallen = kobjsize((void *)textpos);
-                       if (reallen > len) {
-                               textpos = do_mremap(textpos, len, reallen,
-                                       MREMAP_FIXED, textpos);
-                       }
-               }
                up_write(&current->mm->mmap_sem);
 
                if (!textpos  || textpos >= (unsigned long) -4096) {
@@ -622,7 +608,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
                                MAX_SHARED_LIBS * sizeof(unsigned long));
                memp = textpos;
-
+               memp_size = len;
 #ifdef CONFIG_BINFMT_ZFLAT
                /*
                 * load it all in and treat it like a RAM load from now on
@@ -680,10 +666,12 @@ static int load_flat_file(struct linux_binprm * bprm,
                 * set up the brk stuff, uses any slack left in data/bss/stack
                 * allocation.  We put the brk after the bss (between the bss
                 * and stack) like other platforms.
+                * Userspace code relies on the stack pointer starting out at
+                * an address right at the end of a page.
                 */
                current->mm->start_brk = datapos + data_len + bss_len;
                current->mm->brk = (current->mm->start_brk + 3) & ~3;
-               current->mm->context.end_brk = memp + kobjsize((void *) memp) - stack_len;
+               current->mm->context.end_brk = memp + memp_size - stack_len;
        }
 
        if (flags & FLAT_FLAG_KTRACE)
@@ -790,8 +778,8 @@ static int load_flat_file(struct linux_binprm * bprm,
 
        /* zero the BSS,  BRK and stack areas */
        memset((void*)(datapos + data_len), 0, bss_len + 
-                       (memp + kobjsize((void *) memp) - stack_len -   /* end brk */
-                       libinfo->lib_list[id].start_brk) +              /* start brk */
+                       (memp + memp_size - stack_len -         /* end brk */
+                       libinfo->lib_list[id].start_brk) +      /* start brk */
                        stack_len);
 
        return 0;
@@ -880,7 +868,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                                        (libinfo.lib_list[j].loaded)?
                                                libinfo.lib_list[j].start_data:UNLOADED_LIB;
 
-       compute_creds(bprm);
+       install_exec_creds(bprm);
        current->flags &= ~PF_FORKNOEXEC;
 
        set_binfmt(&flat_format);
@@ -914,7 +902,9 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        /* Stash our initial stack pointer into the mm structure */
        current->mm->start_stack = (unsigned long )sp;
 
-       
+#ifdef FLAT_PLAT_INIT
+       FLAT_PLAT_INIT(regs);
+#endif
        DBG_FLT("start_thread(regs=0x%x, entry=0x%x, start_stack=0x%x)\n",
                (int)regs, (int)start_addr, (int)current->mm->start_stack);