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(&current->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(&current->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

Reply via email to