#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <asm/cacheflush.h>
+#include <asm/page.h>
/****************************************************************************/
#define DBG_FLT(a...)
#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 UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
int envc = bprm->envc;
char uninitialized_var(dummy);
- sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p);
-
- sp -= envc+1;
- envp = sp;
- sp -= argc+1;
- argv = sp;
+ 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);
- flat_stack_align(sp);
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;
while (argc-->0) {
put_user((unsigned long) p, argv++);
ret = realdatastart;
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",
(int)(data_len + bss_len + stack_len), (int)datapos);
}
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_size = len;
#ifdef CONFIG_BINFMT_ZFLAT
if (IS_ERR(bprm.file))
return res;
+ bprm.cred = prepare_exec_creds();
+ res = -ENOMEM;
+ if (!bprm.cred)
+ goto out;
+
res = prepare_binprm(&bprm);
if (res <= (unsigned long)-4096)
res = load_flat_file(&bprm, libs, id, NULL);
- if (bprm.file) {
- allow_write_access(bprm.file);
- fput(bprm.file);
- bprm.file = NULL;
- }
+
+ abort_creds(bprm.cred);
+
+out:
+ allow_write_access(bprm.file);
+ fput(bprm.file);
+
return(res);
}
stack_len = TOP_OF_ARGS - bprm->p; /* the strings */
stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv 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);
if (res > (unsigned long)-4096)