Commit 4f9a58d7 authored by Olaf Hering's avatar Olaf Hering Committed by Linus Torvalds

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: default avatarOlaf 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f77e3498
...@@ -175,6 +175,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, ...@@ -175,6 +175,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
/* Create the ELF interpreter info */ /* Create the ELF interpreter info */
elf_info = (elf_addr_t *)current->mm->saved_auxv; 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) \ #define NEW_AUX_ENT(id, val) \
do { \ do { \
elf_info[ei_index++] = id; \ elf_info[ei_index++] = id; \
...@@ -185,6 +186,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, ...@@ -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 * ARCH_DLINFO must come first so PPC can do its special alignment of
* AUXV. * AUXV.
* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT() in
* ARCH_DLINFO changes
*/ */
ARCH_DLINFO; ARCH_DLINFO;
#endif #endif
......
...@@ -155,6 +155,7 @@ extern int alpha_l1d_cacheshape; ...@@ -155,6 +155,7 @@ extern int alpha_l1d_cacheshape;
extern int alpha_l2_cacheshape; extern int alpha_l2_cacheshape;
extern int alpha_l3_cacheshape; extern int alpha_l3_cacheshape;
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#define ARCH_DLINFO \ #define ARCH_DLINFO \
do { \ do { \
NEW_AUX_ENT(AT_L1I_CACHESHAPE, alpha_l1i_cacheshape); \ NEW_AUX_ENT(AT_L1I_CACHESHAPE, alpha_l1i_cacheshape); \
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/kernel.h> #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 * This is the logout header that should be common to all platforms
......
...@@ -192,6 +192,7 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); ...@@ -192,6 +192,7 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
#define GATE_EHDR ((const struct elfhdr *) GATE_ADDR) #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 \ #define ARCH_DLINFO \
do { \ do { \
extern char __kernel_syscall_via_epc[]; \ extern char __kernel_syscall_via_epc[]; \
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */
struct pci_vector_struct { struct pci_vector_struct {
__u16 segment; /* PCI Segment number */ __u16 segment; /* PCI Segment number */
__u16 bus; /* PCI Bus number */ __u16 bus; /* PCI Bus number */
......
...@@ -291,6 +291,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, ...@@ -291,6 +291,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
* AT_IGNOREPPC is used for that. * AT_IGNOREPPC is used for that.
* - for compatibility with glibc ARCH_DLINFO must always be defined on PPC, * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
* even if DLINFO_ARCH_ITEMS goes to zero or is undefined. * 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 \ #define ARCH_DLINFO \
do { \ do { \
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define set_mb(var, value) do { var = value; mb(); } while (0) #define set_mb(var, value) do { var = value; mb(); } while (0)
#ifdef __KERNEL__ #ifdef __KERNEL__
#define AT_VECTOR_SIZE_ARCH 6 /* entries in ARCH_DLINFO */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define smp_mb() mb() #define smp_mb() mb()
#define smp_rmb() rmb() #define smp_rmb() rmb()
......
...@@ -133,6 +133,7 @@ extern void __kernel_vsyscall; ...@@ -133,6 +133,7 @@ extern void __kernel_vsyscall;
#define VDSO_BASE ((unsigned long)current->mm->context.vdso) #define VDSO_BASE ((unsigned long)current->mm->context.vdso)
#define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x)) #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 \ #define ARCH_DLINFO \
do { \ do { \
if (vdso_enabled) \ if (vdso_enabled) \
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next); struct task_struct *next);
#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
/* /*
* switch_to() should switch tasks to task nr n, first * switch_to() should switch tasks to task nr n, first
*/ */
......
...@@ -153,6 +153,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, ...@@ -153,6 +153,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
extern unsigned int vdso_enabled; extern unsigned int vdso_enabled;
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#define ARCH_DLINFO \ #define ARCH_DLINFO \
do if (vdso_enabled) { \ do if (vdso_enabled) { \
NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <asm/cmpxchg.h> #include <asm/cmpxchg.h>
#ifdef __KERNEL__ #ifdef __KERNEL__
#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */
struct task_struct; /* one of the stranger aspects of C forward declarations.. */ 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)); extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#define AT_SECURE 23 /* secure mode boolean */ #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 */ #endif /* _LINUX_AUXVEC_H */
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#define _LINUX_ELF_H #define _LINUX_ELF_H
#include <linux/types.h> #include <linux/types.h>
#include <linux/auxvec.h>
#include <linux/elf-em.h> #include <linux/elf-em.h>
#include <asm/elf.h> #include <asm/elf.h>
......
#ifndef _LINUX_MM_TYPES_H #ifndef _LINUX_MM_TYPES_H
#define _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/types.h>
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/list.h> #include <linux/list.h>
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/mmu.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; struct address_space;
#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment