Commit c3dc5bec05a2ae03a72ef82e321d77fb549d951c

Authored by Oskar Schirmer
Committed by Linus Torvalds
1 parent ba9447198b

flat: fix data sections alignment

The flat loader uses an architecture's flat_stack_align() to align the
stack but assumes word-alignment is enough for the data sections.

However, on the Xtensa S6000 we have registers up to 128bit width
which can be used from userspace and therefor need userspace stack and
data-section alignment of at least this size.

This patch drops flat_stack_align() and uses the same alignment that
is required for slab caches, ARCH_SLAB_MINALIGN, or wordsize if it's
not defined by the architecture.

It also fixes m32r which was obviously kaput, aligning an
uninitialized stack entry instead of the stack pointer.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Oskar Schirmer <os@emlix.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Bryan Wu <cooloney@kernel.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Cc: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: Johannes Weiner <jw@emlix.com>
Acked-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 7 changed files with 31 additions and 23 deletions Side-by-side Diff

arch/arm/include/asm/flat.h
... ... @@ -5,9 +5,6 @@
5 5 #ifndef __ARM_FLAT_H__
6 6 #define __ARM_FLAT_H__
7 7  
8   -/* An odd number of words will be pushed after this alignment, so
9   - deliberately misalign the value. */
10   -#define flat_stack_align(sp) sp = (void *)(((unsigned long)(sp) - 4) | 4)
11 8 #define flat_argvp_envp_on_stack() 1
12 9 #define flat_old_ram_flag(flags) (flags)
13 10 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
arch/blackfin/include/asm/flat.h
... ... @@ -10,7 +10,6 @@
10 10  
11 11 #include <asm/unaligned.h>
12 12  
13   -#define flat_stack_align(sp) /* nothing needed */
14 13 #define flat_argvp_envp_on_stack() 0
15 14 #define flat_old_ram_flag(flags) (flags)
16 15  
arch/h8300/include/asm/flat.h
... ... @@ -5,7 +5,6 @@
5 5 #ifndef __H8300_FLAT_H__
6 6 #define __H8300_FLAT_H__
7 7  
8   -#define flat_stack_align(sp) /* nothing needed */
9 8 #define flat_argvp_envp_on_stack() 1
10 9 #define flat_old_ram_flag(flags) 1
11 10 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
arch/m32r/include/asm/flat.h
... ... @@ -12,7 +12,6 @@
12 12 #ifndef __ASM_M32R_FLAT_H
13 13 #define __ASM_M32R_FLAT_H
14 14  
15   -#define flat_stack_align(sp) (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0))
16 15 #define flat_argvp_envp_on_stack() 0
17 16 #define flat_old_ram_flag(flags) (flags)
18 17 #define flat_set_persistent(relval, p) 0
arch/m68k/include/asm/flat.h
... ... @@ -5,7 +5,6 @@
5 5 #ifndef __M68KNOMMU_FLAT_H__
6 6 #define __M68KNOMMU_FLAT_H__
7 7  
8   -#define flat_stack_align(sp) /* nothing needed */
9 8 #define flat_argvp_envp_on_stack() 1
10 9 #define flat_old_ram_flag(flags) (flags)
11 10 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
arch/sh/include/asm/flat.h
... ... @@ -12,7 +12,6 @@
12 12 #ifndef __ASM_SH_FLAT_H
13 13 #define __ASM_SH_FLAT_H
14 14  
15   -#define flat_stack_align(sp) /* nothing needed */
16 15 #define flat_argvp_envp_on_stack() 0
17 16 #define flat_old_ram_flag(flags) (flags)
18 17 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
... ... @@ -41,6 +41,7 @@
41 41 #include <asm/uaccess.h>
42 42 #include <asm/unaligned.h>
43 43 #include <asm/cacheflush.h>
  44 +#include <asm/page.h>
44 45  
45 46 /****************************************************************************/
46 47  
... ... @@ -54,6 +55,18 @@
54 55 #define DBG_FLT(a...)
55 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 70 #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
58 71 #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
59 72  
60 73  
61 74  
62 75  
... ... @@ -114,20 +127,18 @@
114 127 int envc = bprm->envc;
115 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 136 if (flat_argvp_envp_on_stack()) {
126   - --sp; put_user((unsigned long) envp, sp);
127   - --sp; put_user((unsigned long) argv, sp);
  137 + put_user((unsigned long) envp, sp + 2);
  138 + put_user((unsigned long) argv, sp + 1);
128 139 }
129 140  
130   - put_user(argc,--sp);
  141 + put_user(argc, sp);
131 142 current->mm->arg_start = (unsigned long) p;
132 143 while (argc-->0) {
133 144 put_user((unsigned long) p, argv++);
... ... @@ -558,7 +569,9 @@
558 569 ret = realdatastart;
559 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 576 DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
564 577 (int)(data_len + bss_len + stack_len), (int)datapos);
... ... @@ -604,9 +617,12 @@
604 617 }
605 618  
606 619 realdatastart = textpos + ntohl(hdr->data_start);
607   - datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
608   - reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
609   - MAX_SHARED_LIBS * sizeof(unsigned long));
  620 + datapos = ALIGN(realdatastart +
  621 + MAX_SHARED_LIBS * sizeof(unsigned long),
  622 + FLAT_DATA_ALIGN);
  623 +
  624 + reloc = (unsigned long *)
  625 + (datapos + (ntohl(hdr->reloc_start) - text_len));
610 626 memp = textpos;
611 627 memp_size = len;
612 628 #ifdef CONFIG_BINFMT_ZFLAT
... ... @@ -854,7 +870,7 @@
854 870 stack_len = TOP_OF_ARGS - bprm->p; /* the strings */
855 871 stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
856 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 875 res = load_flat_file(bprm, &libinfo, 0, &stack_len);
860 876 if (res > (unsigned long)-4096)