increase AT_VECTOR_SIZE to terminate saved_auxv properly
authorOlaf Hering <olaf@aepfle.de>
Wed, 17 Oct 2007 06:30:12 +0000 (23:30 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Wed, 17 Oct 2007 15:43:00 +0000 (08:43 -0700)
include/asm-powerpc/elf.h has 6 entries in ARCH_DLINFO.  fs/binfmt_elf.c
has 14 unconditional NEW_AUX_ENT entries and 2 conditional NEW_AUX_ENT
entries.  So in the worst case, saved_auxv does not get an AT_NULL entry at
the end.

The saved_auxv array must be terminated with an AT_NULL entry.  Make the
size of mm_struct->saved_auxv arch dependend, based on the number of
ARCH_DLINFO entries.

Signed-off-by: Olaf Hering <olh@suse.de>
Cc: Roland McGrath <roland@redhat.com>
Cc: Jakub Jelinek <jakub@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
14 files changed:
fs/binfmt_elf.c
include/asm-alpha/elf.h
include/asm-alpha/system.h
include/asm-ia64/elf.h
include/asm-ia64/system.h
include/asm-powerpc/elf.h
include/asm-powerpc/system.h
include/asm-sh/elf.h
include/asm-sh/system.h
include/asm-x86/elf_32.h
include/asm-x86/system_32.h
include/linux/auxvec.h
include/linux/elf.h
include/linux/mm_types.h

index 4263326ede0461a201d35ece02b28275ab3ac79a..0f55b71ed98354011b2fbf7b90939a7e32713557 100644 (file)
@@ -175,6 +175,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
 
        /* Create the ELF interpreter info */
        elf_info = (elf_addr_t *)current->mm->saved_auxv;
+       /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
 #define NEW_AUX_ENT(id, val) \
        do { \
                elf_info[ei_index++] = id; \
@@ -185,6 +186,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
        /* 
         * ARCH_DLINFO must come first so PPC can do its special alignment of
         * AUXV.
+        * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT() in
+        * ARCH_DLINFO changes
         */
        ARCH_DLINFO;
 #endif
index 6c2d78fba264ac21ce616fcf9622bf1ea9b89fc7..4b518e3b952c2e607993d4e5ebf0b64c01b83d14 100644 (file)
@@ -155,6 +155,7 @@ extern int alpha_l1d_cacheshape;
 extern int alpha_l2_cacheshape;
 extern int alpha_l3_cacheshape;
 
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 #define ARCH_DLINFO                                            \
   do {                                                         \
     NEW_AUX_ENT(AT_L1I_CACHESHAPE, alpha_l1i_cacheshape);      \
index 620c4d86cbf48d50ae8b254fc147f80fa199b1e7..fd9dc889f36c87b55da179ba39f3528e6cf8e1cb 100644 (file)
@@ -48,6 +48,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/kernel.h>
+#define AT_VECTOR_SIZE_ARCH 4 /* entries in ARCH_DLINFO */
 
 /*
  * This is the logout header that should be common to all platforms
index 25f9835d5459e2028c3b1ba1c811861bb2d19193..f10e29b60b0010b322b3aec2242b3dfb6a5de66e 100644 (file)
@@ -192,6 +192,7 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 
 #define GATE_EHDR      ((const struct elfhdr *) GATE_ADDR)
 
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 #define ARCH_DLINFO                                                            \
 do {                                                                           \
        extern char __kernel_syscall_via_epc[];                                 \
index 91bb8e00066c76b5a59c00fd3f8a4649ba6e7fb7..595112bca3ccc8f39448dedcf9e195c6ac1f94d4 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 
+#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */
+
 struct pci_vector_struct {
        __u16 segment;  /* PCI Segment number */
        __u16 bus;      /* PCI Bus number */
index 8925c28136671d32294d5b54ccff0e34968ae1f5..6bd07ef78ac42b27aac921d650a2b04f6856c45b 100644 (file)
@@ -291,6 +291,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
  *   AT_IGNOREPPC is used for that.
  * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
  *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+ * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
  */
 #define ARCH_DLINFO                                                    \
 do {                                                                   \
index d10e99bf500119972d6ef6579ada5b1164136ce4..87be8c3bc9cb25efb11aebac0734caaa5fe5e85a 100644 (file)
@@ -40,6 +40,7 @@
 #define set_mb(var, value)     do { var = value; mb(); } while (0)
 
 #ifdef __KERNEL__
+#define AT_VECTOR_SIZE_ARCH 6 /* entries in ARCH_DLINFO */
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
 #define smp_rmb()      rmb()
index 43ca244564b104a6d3438a7c3d86225fc5e12290..12cc4b392bf039efbace9fa6090521b1d08b3799 100644 (file)
@@ -133,6 +133,7 @@ extern void __kernel_vsyscall;
 #define VDSO_BASE              ((unsigned long)current->mm->context.vdso)
 #define VDSO_SYM(x)            (VDSO_BASE + (unsigned long)(x))
 
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 #define ARCH_DLINFO                                            \
 do {                                                           \
        if (vdso_enabled)                                       \
index 9d849e6df268b8138252e29f11126f31c21ee2b7..4faa2fb886163007f57af8ec54ad45769b2bf2d3 100644 (file)
@@ -15,6 +15,7 @@
 struct task_struct *__switch_to(struct task_struct *prev,
                                struct task_struct *next);
 
+#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
 /*
  *     switch_to() should switch tasks to task nr n, first
  */
index af45f315435b76bd2017c87f07c855a9edc90ce4..b3f694eaaf37a6f7238b1a653c58399c3d877b4c 100644 (file)
@@ -153,6 +153,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 extern unsigned int vdso_enabled;
 
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 #define ARCH_DLINFO                                                    \
 do if (vdso_enabled) {                                                 \
                NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY);                    \
index e7e5d426fef58c2b6892fea59c341528d827afaf..d84e593b7dfc69645240040432eab4e3398d3af8 100644 (file)
@@ -7,6 +7,7 @@
 #include <asm/cmpxchg.h>
 
 #ifdef __KERNEL__
+#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */
 
 struct task_struct;    /* one of the stranger aspects of C forward declarations.. */
 extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
index d2bc0d66e65d49ed3df74f2666b3d079a023eeca..ad895455ab72cebf26a218910433a34edd53e30d 100644 (file)
@@ -26,6 +26,8 @@
 
 #define AT_SECURE 23   /* secure mode boolean */
 
-#define AT_VECTOR_SIZE  44 /* Size of auxiliary table.  */
+#ifdef __KERNEL__
+#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */
+#endif
 
 #endif /* _LINUX_AUXVEC_H */
index 0eb9ed2f4189a675758ca212b27f68b7879afd25..576e83bd6d88e5b6dfcad00a4136106c3c87dbec 100644 (file)
@@ -2,7 +2,6 @@
 #define _LINUX_ELF_H
 
 #include <linux/types.h>
-#include <linux/auxvec.h>
 #include <linux/elf-em.h>
 #include <asm/elf.h>
 
index 877667918452f8c752714c6f6d5905b8352eae30..f4c03e0b355e04dbbbc05f9500350d632ef87bd6 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _LINUX_MM_TYPES_H
 #define _LINUX_MM_TYPES_H
 
-#include <linux/auxvec.h>      /* For AT_VECTOR_SIZE */
+#include <linux/auxvec.h>
 #include <linux/types.h>
 #include <linux/threads.h>
 #include <linux/list.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
 
+#ifndef AT_VECTOR_SIZE_ARCH
+#define AT_VECTOR_SIZE_ARCH 0
+#endif
+#define AT_VECTOR_SIZE (2*(AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1))
+
 struct address_space;
 
 #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS