aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_flat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_flat.c')
-rw-r--r--fs/binfmt_flat.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 5cebf0b37798..697f6b5f1313 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -41,6 +41,7 @@
41#include <asm/uaccess.h> 41#include <asm/uaccess.h>
42#include <asm/unaligned.h> 42#include <asm/unaligned.h>
43#include <asm/cacheflush.h> 43#include <asm/cacheflush.h>
44#include <asm/page.h>
44 45
45/****************************************************************************/ 46/****************************************************************************/
46 47
@@ -54,6 +55,18 @@
54#define DBG_FLT(a...) 55#define DBG_FLT(a...)
55#endif 56#endif
56 57
58/*
59 * User data (stack, data section and bss) needs to be aligned
60 * for the same reasons as SLAB memory is, and to the same amount.
61 * Avoid duplicating architecture specific code by using the same
62 * macro as with SLAB allocation:
63 */
64#ifdef ARCH_SLAB_MINALIGN
65#define FLAT_DATA_ALIGN (ARCH_SLAB_MINALIGN)
66#else
67#define FLAT_DATA_ALIGN (sizeof(void *))
68#endif
69
57#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ 70#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
58#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ 71#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
59 72
@@ -114,20 +127,18 @@ static unsigned long create_flat_tables(
114 int envc = bprm->envc; 127 int envc = bprm->envc;
115 char uninitialized_var(dummy); 128 char uninitialized_var(dummy);
116 129
117 sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p); 130 sp = (unsigned long *)p;
131 sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
132 sp = (unsigned long *) ((unsigned long)sp & -FLAT_DATA_ALIGN);
133 argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
134 envp = argv + (argc + 1);
118 135
119 sp -= envc+1;
120 envp = sp;
121 sp -= argc+1;
122 argv = sp;
123
124 flat_stack_align(sp);
125 if (flat_argvp_envp_on_stack()) { 136 if (flat_argvp_envp_on_stack()) {
126 --sp; put_user((unsigned long) envp, sp); 137 put_user((unsigned long) envp, sp + 2);
127 --sp; put_user((unsigned long) argv, sp); 138 put_user((unsigned long) argv, sp + 1);
128 } 139 }
129 140
130 put_user(argc,--sp); 141 put_user(argc, sp);
131 current->mm->arg_start = (unsigned long) p; 142 current->mm->arg_start = (unsigned long) p;
132 while (argc-->0) { 143 while (argc-->0) {
133 put_user((unsigned long) p, argv++); 144 put_user((unsigned long) p, argv++);
@@ -558,7 +569,9 @@ static int load_flat_file(struct linux_binprm * bprm,
558 ret = realdatastart; 569 ret = realdatastart;
559 goto err; 570 goto err;
560 } 571 }
561 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); 572 datapos = ALIGN(realdatastart +
573 MAX_SHARED_LIBS * sizeof(unsigned long),
574 FLAT_DATA_ALIGN);
562 575
563 DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n", 576 DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
564 (int)(data_len + bss_len + stack_len), (int)datapos); 577 (int)(data_len + bss_len + stack_len), (int)datapos);
@@ -604,9 +617,12 @@ static int load_flat_file(struct linux_binprm * bprm,
604 } 617 }
605 618
606 realdatastart = textpos + ntohl(hdr->data_start); 619 realdatastart = textpos + ntohl(hdr->data_start);
607 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); 620 datapos = ALIGN(realdatastart +
608 reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) + 621 MAX_SHARED_LIBS * sizeof(unsigned long),
609 MAX_SHARED_LIBS * sizeof(unsigned long)); 622 FLAT_DATA_ALIGN);
623
624 reloc = (unsigned long *)
625 (datapos + (ntohl(hdr->reloc_start) - text_len));
610 memp = textpos; 626 memp = textpos;
611 memp_size = len; 627 memp_size = len;
612#ifdef CONFIG_BINFMT_ZFLAT 628#ifdef CONFIG_BINFMT_ZFLAT
@@ -854,7 +870,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
854 stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ 870 stack_len = TOP_OF_ARGS - bprm->p; /* the strings */
855 stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ 871 stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
856 stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ 872 stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */
857 873 stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */
858 874
859 res = load_flat_file(bprm, &libinfo, 0, &stack_len); 875 res = load_flat_file(bprm, &libinfo, 0, &stack_len);
860 if (res > (unsigned long)-4096) 876 if (res > (unsigned long)-4096)