X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fbinfmt_flat.c;h=4b051ad56b281d618359606be62cdc901da08bd7;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=07a21b72f0fe599ca173281a660744ee6c14fd5d;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 07a21b72f..4b051ad56 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -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(¤t->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(¤t->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(¤t->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; }