aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/flat.h3
-rw-r--r--arch/blackfin/include/asm/flat.h1
-rw-r--r--arch/h8300/include/asm/flat.h1
-rw-r--r--arch/m32r/include/asm/flat.h1
-rw-r--r--arch/m68k/include/asm/flat.h1
-rw-r--r--arch/sh/include/asm/flat.h1
-rw-r--r--fs/binfmt_flat.c46
7 files changed, 31 insertions, 23 deletions
diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
index 1d77e51907f..59426a4595c 100644
--- a/arch/arm/include/asm/flat.h
+++ b/arch/arm/include/asm/flat.h
@@ -5,9 +5,6 @@
#ifndef __ARM_FLAT_H__
#define __ARM_FLAT_H__
-/* An odd number of words will be pushed after this alignment, so
- deliberately misalign the value. */
-#define flat_stack_align(sp) sp = (void *)(((unsigned long)(sp) - 4) | 4)
#define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
diff --git a/arch/blackfin/include/asm/flat.h b/arch/blackfin/include/asm/flat.h
index e70074e05f4..733a178d782 100644
--- a/arch/blackfin/include/asm/flat.h
+++ b/arch/blackfin/include/asm/flat.h
@@ -10,7 +10,6 @@
#include <asm/unaligned.h>
-#define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags)
diff --git a/arch/h8300/include/asm/flat.h b/arch/h8300/include/asm/flat.h
index 2a873508a9a..bd12b31b90e 100644
--- a/arch/h8300/include/asm/flat.h
+++ b/arch/h8300/include/asm/flat.h
@@ -5,7 +5,6 @@
#ifndef __H8300_FLAT_H__
#define __H8300_FLAT_H__
-#define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) 1
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
diff --git a/arch/m32r/include/asm/flat.h b/arch/m32r/include/asm/flat.h
index d851cf0c4aa..5d711c4688f 100644
--- a/arch/m32r/include/asm/flat.h
+++ b/arch/m32r/include/asm/flat.h
@@ -12,7 +12,6 @@
#ifndef __ASM_M32R_FLAT_H
#define __ASM_M32R_FLAT_H
-#define flat_stack_align(sp) (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0))
#define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags)
#define flat_set_persistent(relval, p) 0
diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h
index 814b5174a8e..a0e29079397 100644
--- a/arch/m68k/include/asm/flat.h
+++ b/arch/m68k/include/asm/flat.h
@@ -5,7 +5,6 @@
#ifndef __M68KNOMMU_FLAT_H__
#define __M68KNOMMU_FLAT_H__
-#define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
diff --git a/arch/sh/include/asm/flat.h b/arch/sh/include/asm/flat.h
index d3b2b4f109e..5d84df5e27f 100644
--- a/arch/sh/include/asm/flat.h
+++ b/arch/sh/include/asm/flat.h
@@ -12,7 +12,6 @@
#ifndef __ASM_SH_FLAT_H
#define __ASM_SH_FLAT_H
-#define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 5cebf0b3779..697f6b5f131 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -41,6 +41,7 @@
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <asm/cacheflush.h>
+#include <asm/page.h>
/****************************************************************************/
@@ -54,6 +55,18 @@
#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 */
@@ -114,20 +127,18 @@ static unsigned long create_flat_tables(
int envc = bprm->envc;
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()) {
- --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++);
@@ -558,7 +569,9 @@ static int load_flat_file(struct linux_binprm * bprm,
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);
@@ -604,9 +617,12 @@ 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(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
@@ -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 += (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)