|
@@ -41,6 +41,7 @@
|
|
#include <asm/uaccess.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/unaligned.h>
|
|
#include <asm/unaligned.h>
|
|
#include <asm/cacheflush.h>
|
|
#include <asm/cacheflush.h>
|
|
|
|
+#include <asm/page.h>
|
|
|
|
|
|
/****************************************************************************/
|
|
/****************************************************************************/
|
|
|
|
|
|
@@ -54,6 +55,18 @@
|
|
#define DBG_FLT(a...)
|
|
#define DBG_FLT(a...)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * User data (stack, data section and bss) needs to be aligned
|
|
|
|
+ * for the same reasons as SLAB memory is, and to the same amount.
|
|
|
|
+ * Avoid duplicating architecture specific code by using the same
|
|
|
|
+ * macro as with SLAB allocation:
|
|
|
|
+ */
|
|
|
|
+#ifdef ARCH_SLAB_MINALIGN
|
|
|
|
+#define FLAT_DATA_ALIGN (ARCH_SLAB_MINALIGN)
|
|
|
|
+#else
|
|
|
|
+#define FLAT_DATA_ALIGN (sizeof(void *))
|
|
|
|
+#endif
|
|
|
|
+
|
|
#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
|
|
#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
|
|
#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
|
|
#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
|
|
|
|
|
|
@@ -114,20 +127,18 @@ static unsigned long create_flat_tables(
|
|
int envc = bprm->envc;
|
|
int envc = bprm->envc;
|
|
char uninitialized_var(dummy);
|
|
char uninitialized_var(dummy);
|
|
|
|
|
|
- sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p);
|
|
|
|
|
|
+ sp = (unsigned long *)p;
|
|
|
|
+ sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
|
|
|
|
+ sp = (unsigned long *) ((unsigned long)sp & -FLAT_DATA_ALIGN);
|
|
|
|
+ argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
|
|
|
|
+ envp = argv + (argc + 1);
|
|
|
|
|
|
- sp -= envc+1;
|
|
|
|
- envp = sp;
|
|
|
|
- sp -= argc+1;
|
|
|
|
- argv = sp;
|
|
|
|
-
|
|
|
|
- flat_stack_align(sp);
|
|
|
|
if (flat_argvp_envp_on_stack()) {
|
|
if (flat_argvp_envp_on_stack()) {
|
|
- --sp; put_user((unsigned long) envp, sp);
|
|
|
|
- --sp; put_user((unsigned long) argv, sp);
|
|
|
|
|
|
+ put_user((unsigned long) envp, sp + 2);
|
|
|
|
+ put_user((unsigned long) argv, sp + 1);
|
|
}
|
|
}
|
|
|
|
|
|
- put_user(argc,--sp);
|
|
|
|
|
|
+ put_user(argc, sp);
|
|
current->mm->arg_start = (unsigned long) p;
|
|
current->mm->arg_start = (unsigned long) p;
|
|
while (argc-->0) {
|
|
while (argc-->0) {
|
|
put_user((unsigned long) p, argv++);
|
|
put_user((unsigned long) p, argv++);
|
|
@@ -558,7 +569,9 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|
ret = realdatastart;
|
|
ret = realdatastart;
|
|
goto err;
|
|
goto err;
|
|
}
|
|
}
|
|
- datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
|
|
|
|
|
|
+ datapos = ALIGN(realdatastart +
|
|
|
|
+ MAX_SHARED_LIBS * sizeof(unsigned long),
|
|
|
|
+ FLAT_DATA_ALIGN);
|
|
|
|
|
|
DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
|
|
DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
|
|
(int)(data_len + bss_len + stack_len), (int)datapos);
|
|
(int)(data_len + bss_len + stack_len), (int)datapos);
|
|
@@ -604,9 +617,12 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|
}
|
|
}
|
|
|
|
|
|
realdatastart = textpos + ntohl(hdr->data_start);
|
|
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(realdatastart +
|
|
|
|
+ MAX_SHARED_LIBS * sizeof(unsigned long),
|
|
|
|
+ FLAT_DATA_ALIGN);
|
|
|
|
+
|
|
|
|
+ reloc = (unsigned long *)
|
|
|
|
+ (datapos + (ntohl(hdr->reloc_start) - text_len));
|
|
memp = textpos;
|
|
memp = textpos;
|
|
memp_size = len;
|
|
memp_size = len;
|
|
#ifdef CONFIG_BINFMT_ZFLAT
|
|
#ifdef CONFIG_BINFMT_ZFLAT
|
|
@@ -854,7 +870,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
|
stack_len = TOP_OF_ARGS - bprm->p; /* the strings */
|
|
stack_len = TOP_OF_ARGS - bprm->p; /* the strings */
|
|
stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
|
|
stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
|
|
stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */
|
|
stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */
|
|
-
|
|
|
|
|
|
+ stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */
|
|
|
|
|
|
res = load_flat_file(bprm, &libinfo, 0, &stack_len);
|
|
res = load_flat_file(bprm, &libinfo, 0, &stack_len);
|
|
if (res > (unsigned long)-4096)
|
|
if (res > (unsigned long)-4096)
|