From: Jie Zhang <[email protected]> If a structure in the data section attempts to force a larger alignment, the FLAT loader will break this when working with shared flat libraries by inserting a few words before the data section.
URL: http://blackfin.uclinux.org/gf/tracker/4854 Signed-off-by: Jie Zhang <[email protected]> Signed-off-by: Mike Frysinger <[email protected]> --- fs/binfmt_flat.c | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 5cebf0b..51d2e0e 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -542,7 +542,9 @@ static int load_flat_file(struct linux_binprm * bprm, goto err; } - len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); + len = MAX_SHARED_LIBS * sizeof(unsigned long); + len = ALIGN(len, 0x20); + len = data_len + extra; len = PAGE_ALIGN(len); down_write(¤t->mm->mmap_sem); realdatastart = do_mmap(0, 0, len, @@ -559,6 +561,7 @@ static int load_flat_file(struct linux_binprm * bprm, goto err; } datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); + datapos = ALIGN(datapos, 0x20); DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n", (int)(data_len + bss_len + stack_len), (int)datapos); @@ -577,7 +580,7 @@ static int load_flat_file(struct linux_binprm * bprm, if (result >= (unsigned long)-4096) { 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); + do_munmap(current->mm, realdatastart, len); ret = result; goto err; } @@ -587,7 +590,8 @@ static int load_flat_file(struct linux_binprm * bprm, memp_size = len; } else { - len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); + len = text_len + MAX_SHARED_LIBS * sizeof(unsigned long); + len = ALIGN(len, 0x20) + data_len + extra; len = PAGE_ALIGN(len); down_write(¤t->mm->mmap_sem); textpos = do_mmap(0, 0, len, @@ -605,8 +609,8 @@ static int load_flat_file(struct linux_binprm * bprm, realdatastart = textpos + ntohl(hdr->data_start); datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); - reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) + - MAX_SHARED_LIBS * sizeof(unsigned long)); + datapos = ALIGN(datapos, 0x20); + reloc = (unsigned long *) (datapos + ntohl(hdr->reloc_start) - text_len); memp = textpos; memp_size = len; #ifdef CONFIG_BINFMT_ZFLAT @@ -643,8 +647,7 @@ static int load_flat_file(struct linux_binprm * bprm, } if (result >= (unsigned long)-4096) { 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)); + do_munmap(current->mm, textpos, len); ret = result; goto err; } @@ -892,7 +895,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) #ifdef CONFIG_BINFMT_SHARED_FLAT for (i = MAX_SHARED_LIBS-1; i>0; i--) { if (libinfo.lib_list[i].loaded) { - /* Push previos first to call address */ + /* Push previous first to call address */ --sp; put_user(start_addr, sp); start_addr = libinfo.lib_list[i].entry; } -- 1.6.3.1 _______________________________________________ uClinux-dev mailing list [email protected] http://mailman.uclinux.org/mailman/listinfo/uclinux-dev This message was resent by [email protected] To unsubscribe see: http://mailman.uclinux.org/mailman/options/uclinux-dev
