From 4f9a58d75bfe82ab2b8ba5b8506dfb190a267834 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 16 Oct 2007 23:30:12 -0700 Subject: [PATCH] increase AT_VECTOR_SIZE to terminate saved_auxv properly 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 Cc: Roland McGrath Cc: Jakub Jelinek Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: "Luck, Tony" Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_elf.c | 3 +++ include/asm-alpha/elf.h | 1 + include/asm-alpha/system.h | 1 + include/asm-ia64/elf.h | 1 + include/asm-ia64/system.h | 2 ++ include/asm-powerpc/elf.h | 1 + include/asm-powerpc/system.h | 1 + include/asm-sh/elf.h | 1 + include/asm-sh/system.h | 1 + include/asm-x86/elf_32.h | 1 + include/asm-x86/system_32.h | 1 + include/linux/auxvec.h | 4 +++- include/linux/elf.h | 1 - include/linux/mm_types.h | 7 ++++++- 14 files changed, 23 insertions(+), 3 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 4263326ede..0f55b71ed9 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -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 diff --git a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h index 6c2d78fba2..4b518e3b95 100644 --- a/include/asm-alpha/elf.h +++ b/include/asm-alpha/elf.h @@ -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); \ diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index 620c4d86cb..fd9dc889f3 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -48,6 +48,7 @@ #ifndef __ASSEMBLY__ #include +#define AT_VECTOR_SIZE_ARCH 4 /* entries in ARCH_DLINFO */ /* * This is the logout header that should be common to all platforms diff --git a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h index 25f9835d54..f10e29b60b 100644 --- a/include/asm-ia64/elf.h +++ b/include/asm-ia64/elf.h @@ -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[]; \ diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index 91bb8e0006..595112bca3 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h @@ -32,6 +32,8 @@ #include #include +#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */ + struct pci_vector_struct { __u16 segment; /* PCI Segment number */ __u16 bus; /* PCI Bus number */ diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h index 8925c28136..6bd07ef78a 100644 --- a/include/asm-powerpc/elf.h +++ b/include/asm-powerpc/elf.h @@ -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 { \ diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index d10e99bf50..87be8c3bc9 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -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() diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h index 43ca244564..12cc4b392b 100644 --- a/include/asm-sh/elf.h +++ b/include/asm-sh/elf.h @@ -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) \ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 9d849e6df2..4faa2fb886 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -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 */ diff --git a/include/asm-x86/elf_32.h b/include/asm-x86/elf_32.h index af45f31543..b3f694eaaf 100644 --- a/include/asm-x86/elf_32.h +++ b/include/asm-x86/elf_32.h @@ -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); \ diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h index e7e5d426fe..d84e593b7d 100644 --- a/include/asm-x86/system_32.h +++ b/include/asm-x86/system_32.h @@ -7,6 +7,7 @@ #include #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)); diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h index d2bc0d66e6..ad895455ab 100644 --- a/include/linux/auxvec.h +++ b/include/linux/auxvec.h @@ -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 */ diff --git a/include/linux/elf.h b/include/linux/elf.h index 0eb9ed2f41..576e83bd6d 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -2,7 +2,6 @@ #define _LINUX_ELF_H #include -#include #include #include diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 8776679184..f4c03e0b35 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -1,7 +1,7 @@ #ifndef _LINUX_MM_TYPES_H #define _LINUX_MM_TYPES_H -#include /* For AT_VECTOR_SIZE */ +#include #include #include #include @@ -13,6 +13,11 @@ #include #include +#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 -- 2.39.5