xref: /openbmc/linux/fs/binfmt_elf.c (revision ca2478a7d974f38d29d27acb42a952c7f168916e)
109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * linux/fs/binfmt_elf.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * These are the functions used to load ELF format executables as used
61da177e4SLinus Torvalds  * on SVr4 machines.  Information on the format may be found in the book
71da177e4SLinus Torvalds  * "UNIX SYSTEM V RELEASE 4 Programmers Guide: Ansi C and Programming Support
81da177e4SLinus Torvalds  * Tools".
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
111da177e4SLinus Torvalds  */
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds #include <linux/module.h>
141da177e4SLinus Torvalds #include <linux/kernel.h>
151da177e4SLinus Torvalds #include <linux/fs.h>
16ce81bb25SChris Kennelly #include <linux/log2.h>
171da177e4SLinus Torvalds #include <linux/mm.h>
181da177e4SLinus Torvalds #include <linux/mman.h>
191da177e4SLinus Torvalds #include <linux/errno.h>
201da177e4SLinus Torvalds #include <linux/signal.h>
211da177e4SLinus Torvalds #include <linux/binfmts.h>
221da177e4SLinus Torvalds #include <linux/string.h>
231da177e4SLinus Torvalds #include <linux/file.h>
241da177e4SLinus Torvalds #include <linux/slab.h>
251da177e4SLinus Torvalds #include <linux/personality.h>
261da177e4SLinus Torvalds #include <linux/elfcore.h>
271da177e4SLinus Torvalds #include <linux/init.h>
281da177e4SLinus Torvalds #include <linux/highuid.h>
291da177e4SLinus Torvalds #include <linux/compiler.h>
301da177e4SLinus Torvalds #include <linux/highmem.h>
3103911132SAnshuman Khandual #include <linux/hugetlb.h>
321da177e4SLinus Torvalds #include <linux/pagemap.h>
332aa362c4SDenys Vlasenko #include <linux/vmalloc.h>
341da177e4SLinus Torvalds #include <linux/security.h>
351da177e4SLinus Torvalds #include <linux/random.h>
36f4e5cc2cSJesper Juhl #include <linux/elf.h>
37d1fd836dSKees Cook #include <linux/elf-randomize.h>
387e80d0d0SAlexey Dobriyan #include <linux/utsname.h>
39088e7af7SDaisuke HATAYAMA #include <linux/coredump.h>
406fac4829SFrederic Weisbecker #include <linux/sched.h>
41f7ccbae4SIngo Molnar #include <linux/sched/coredump.h>
4268db0cf1SIngo Molnar #include <linux/sched/task_stack.h>
4332ef5517SIngo Molnar #include <linux/sched/cputime.h>
4400e19ceeSDave Martin #include <linux/sizes.h>
4500e19ceeSDave Martin #include <linux/types.h>
465b825c3aSIngo Molnar #include <linux/cred.h>
475037835cSRoss Zwisler #include <linux/dax.h>
487c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
49317c8194SMathieu Desnoyers #include <linux/rseq.h>
501da177e4SLinus Torvalds #include <asm/param.h>
511da177e4SLinus Torvalds #include <asm/page.h>
521da177e4SLinus Torvalds 
5300e19ceeSDave Martin #ifndef ELF_COMPAT
5400e19ceeSDave Martin #define ELF_COMPAT 0
5500e19ceeSDave Martin #endif
5600e19ceeSDave Martin 
572aa362c4SDenys Vlasenko #ifndef user_long_t
582aa362c4SDenys Vlasenko #define user_long_t long
592aa362c4SDenys Vlasenko #endif
6049ae4d4bSDenys Vlasenko #ifndef user_siginfo_t
6149ae4d4bSDenys Vlasenko #define user_siginfo_t siginfo_t
6249ae4d4bSDenys Vlasenko #endif
6349ae4d4bSDenys Vlasenko 
644755200bSNicolas Pitre /* That's for binfmt_elf_fdpic to deal with */
654755200bSNicolas Pitre #ifndef elf_check_fdpic
664755200bSNicolas Pitre #define elf_check_fdpic(ex) false
674755200bSNicolas Pitre #endif
684755200bSNicolas Pitre 
6971613c3bSAl Viro static int load_elf_binary(struct linux_binprm *bprm);
701da177e4SLinus Torvalds 
7169369a70SJosh Triplett #ifdef CONFIG_USELIB
7269369a70SJosh Triplett static int load_elf_library(struct file *);
7369369a70SJosh Triplett #else
7469369a70SJosh Triplett #define load_elf_library NULL
7569369a70SJosh Triplett #endif
7669369a70SJosh Triplett 
771da177e4SLinus Torvalds /*
781da177e4SLinus Torvalds  * If we don't support core dumping, then supply a NULL so we
791da177e4SLinus Torvalds  * don't even try.
801da177e4SLinus Torvalds  */
81698ba7b5SChristoph Hellwig #ifdef CONFIG_ELF_CORE
82f6151dfeSMasami Hiramatsu static int elf_core_dump(struct coredump_params *cprm);
831da177e4SLinus Torvalds #else
841da177e4SLinus Torvalds #define elf_core_dump	NULL
851da177e4SLinus Torvalds #endif
861da177e4SLinus Torvalds 
871da177e4SLinus Torvalds #if ELF_EXEC_PAGESIZE > PAGE_SIZE
881da177e4SLinus Torvalds #define ELF_MIN_ALIGN	ELF_EXEC_PAGESIZE
891da177e4SLinus Torvalds #else
901da177e4SLinus Torvalds #define ELF_MIN_ALIGN	PAGE_SIZE
911da177e4SLinus Torvalds #endif
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds #ifndef ELF_CORE_EFLAGS
941da177e4SLinus Torvalds #define ELF_CORE_EFLAGS	0
951da177e4SLinus Torvalds #endif
961da177e4SLinus Torvalds 
9710b19249SAlexey Dobriyan #define ELF_PAGESTART(_v) ((_v) & ~(int)(ELF_MIN_ALIGN-1))
981da177e4SLinus Torvalds #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))
991da177e4SLinus Torvalds #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1))
1001da177e4SLinus Torvalds 
1011da177e4SLinus Torvalds static struct linux_binfmt elf_format = {
1021da177e4SLinus Torvalds 	.module		= THIS_MODULE,
1031da177e4SLinus Torvalds 	.load_binary	= load_elf_binary,
1041da177e4SLinus Torvalds 	.load_shlib	= load_elf_library,
105d65bc29bSAlexey Dobriyan #ifdef CONFIG_COREDUMP
1061da177e4SLinus Torvalds 	.core_dump	= elf_core_dump,
1079fbbd4ddSAndi Kleen 	.min_coredump	= ELF_EXEC_PAGESIZE,
108d65bc29bSAlexey Dobriyan #endif
1091da177e4SLinus Torvalds };
1101da177e4SLinus Torvalds 
11118676ffcSAlexey Dobriyan #define BAD_ADDR(x) (unlikely((unsigned long)(x) >= TASK_SIZE))
1121da177e4SLinus Torvalds 
set_brk(unsigned long start,unsigned long end,int prot)11316e72e9bSDenys Vlasenko static int set_brk(unsigned long start, unsigned long end, int prot)
1141da177e4SLinus Torvalds {
1151da177e4SLinus Torvalds 	start = ELF_PAGEALIGN(start);
1161da177e4SLinus Torvalds 	end = ELF_PAGEALIGN(end);
1171da177e4SLinus Torvalds 	if (end > start) {
11816e72e9bSDenys Vlasenko 		/*
11916e72e9bSDenys Vlasenko 		 * Map the last of the bss segment.
12016e72e9bSDenys Vlasenko 		 * If the header is requesting these pages to be
12116e72e9bSDenys Vlasenko 		 * executable, honour that (ppc32 needs this).
12216e72e9bSDenys Vlasenko 		 */
12316e72e9bSDenys Vlasenko 		int error = vm_brk_flags(start, end - start,
12416e72e9bSDenys Vlasenko 				prot & PROT_EXEC ? VM_EXEC : 0);
1255d22fc25SLinus Torvalds 		if (error)
1265d22fc25SLinus Torvalds 			return error;
1271da177e4SLinus Torvalds 	}
1281da177e4SLinus Torvalds 	current->mm->start_brk = current->mm->brk = end;
1291da177e4SLinus Torvalds 	return 0;
1301da177e4SLinus Torvalds }
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds /* We need to explicitly zero any fractional pages
1331da177e4SLinus Torvalds    after the data section (i.e. bss).  This would
1341da177e4SLinus Torvalds    contain the junk from the file that should not
135f4e5cc2cSJesper Juhl    be in memory
136f4e5cc2cSJesper Juhl  */
padzero(unsigned long elf_bss)1371da177e4SLinus Torvalds static int padzero(unsigned long elf_bss)
1381da177e4SLinus Torvalds {
1391da177e4SLinus Torvalds 	unsigned long nbyte;
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 	nbyte = ELF_PAGEOFFSET(elf_bss);
1421da177e4SLinus Torvalds 	if (nbyte) {
1431da177e4SLinus Torvalds 		nbyte = ELF_MIN_ALIGN - nbyte;
1441da177e4SLinus Torvalds 		if (clear_user((void __user *) elf_bss, nbyte))
1451da177e4SLinus Torvalds 			return -EFAULT;
1461da177e4SLinus Torvalds 	}
1471da177e4SLinus Torvalds 	return 0;
1481da177e4SLinus Torvalds }
1491da177e4SLinus Torvalds 
15009c6dd3cSOhad Ben-Cohen /* Let's use some macros to make this stack manipulation a little clearer */
1511da177e4SLinus Torvalds #ifdef CONFIG_STACK_GROWSUP
1521da177e4SLinus Torvalds #define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) + (items))
1531da177e4SLinus Torvalds #define STACK_ROUND(sp, items) \
1541da177e4SLinus Torvalds 	((15 + (unsigned long) ((sp) + (items))) &~ 15UL)
155f4e5cc2cSJesper Juhl #define STACK_ALLOC(sp, len) ({ \
156f4e5cc2cSJesper Juhl 	elf_addr_t __user *old_sp = (elf_addr_t __user *)sp; sp += len; \
157f4e5cc2cSJesper Juhl 	old_sp; })
1581da177e4SLinus Torvalds #else
1591da177e4SLinus Torvalds #define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) - (items))
1601da177e4SLinus Torvalds #define STACK_ROUND(sp, items) \
1611da177e4SLinus Torvalds 	(((unsigned long) (sp - items)) &~ 15UL)
162a43e5e3aSAlexey Dobriyan #define STACK_ALLOC(sp, len) (sp -= len)
1631da177e4SLinus Torvalds #endif
1641da177e4SLinus Torvalds 
165483fad1cSNathan Lynch #ifndef ELF_BASE_PLATFORM
166483fad1cSNathan Lynch /*
167483fad1cSNathan Lynch  * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture.
168483fad1cSNathan Lynch  * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value
169483fad1cSNathan Lynch  * will be copied to the user stack in the same manner as AT_PLATFORM.
170483fad1cSNathan Lynch  */
171483fad1cSNathan Lynch #define ELF_BASE_PLATFORM NULL
172483fad1cSNathan Lynch #endif
173483fad1cSNathan Lynch 
1741da177e4SLinus Torvalds static int
create_elf_tables(struct linux_binprm * bprm,const struct elfhdr * exec,unsigned long interp_load_addr,unsigned long e_entry,unsigned long phdr_addr)175a62c5b1bSAlexey Dobriyan create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
1760da1d500SAkira Kawata 		unsigned long interp_load_addr,
1770da1d500SAkira Kawata 		unsigned long e_entry, unsigned long phdr_addr)
1781da177e4SLinus Torvalds {
17903c6d723SAlexey Dobriyan 	struct mm_struct *mm = current->mm;
1801da177e4SLinus Torvalds 	unsigned long p = bprm->p;
1811da177e4SLinus Torvalds 	int argc = bprm->argc;
1821da177e4SLinus Torvalds 	int envc = bprm->envc;
1831da177e4SLinus Torvalds 	elf_addr_t __user *sp;
1841da177e4SLinus Torvalds 	elf_addr_t __user *u_platform;
185483fad1cSNathan Lynch 	elf_addr_t __user *u_base_platform;
186f06295b4SKees Cook 	elf_addr_t __user *u_rand_bytes;
1871da177e4SLinus Torvalds 	const char *k_platform = ELF_PLATFORM;
188483fad1cSNathan Lynch 	const char *k_base_platform = ELF_BASE_PLATFORM;
189f06295b4SKees Cook 	unsigned char k_rand_bytes[16];
1901da177e4SLinus Torvalds 	int items;
1911da177e4SLinus Torvalds 	elf_addr_t *elf_info;
1922347961bSLaurent Vivier 	elf_addr_t flags = 0;
1931f83d806SAlexey Dobriyan 	int ei_index;
19486a264abSDavid Howells 	const struct cred *cred = current_cred();
195b6a2fea3SOllie Wild 	struct vm_area_struct *vma;
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds 	/*
198d68c9d6aSFranck Bui-Huu 	 * In some cases (e.g. Hyper-Threading), we want to avoid L1
199d68c9d6aSFranck Bui-Huu 	 * evictions by the processes running on the same package. One
200d68c9d6aSFranck Bui-Huu 	 * thing we can do is to shuffle the initial stack for them.
201d68c9d6aSFranck Bui-Huu 	 */
202d68c9d6aSFranck Bui-Huu 
203d68c9d6aSFranck Bui-Huu 	p = arch_align_stack(p);
204d68c9d6aSFranck Bui-Huu 
205d68c9d6aSFranck Bui-Huu 	/*
2061da177e4SLinus Torvalds 	 * If this architecture has a platform capability string, copy it
2071da177e4SLinus Torvalds 	 * to userspace.  In some cases (Sparc), this info is impossible
2081da177e4SLinus Torvalds 	 * for userspace to get any other way, in others (i386) it is
2091da177e4SLinus Torvalds 	 * merely difficult.
2101da177e4SLinus Torvalds 	 */
2111da177e4SLinus Torvalds 	u_platform = NULL;
2121da177e4SLinus Torvalds 	if (k_platform) {
2131da177e4SLinus Torvalds 		size_t len = strlen(k_platform) + 1;
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds 		u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
216646e84deSAl Viro 		if (copy_to_user(u_platform, k_platform, len))
2171da177e4SLinus Torvalds 			return -EFAULT;
2181da177e4SLinus Torvalds 	}
2191da177e4SLinus Torvalds 
220483fad1cSNathan Lynch 	/*
221483fad1cSNathan Lynch 	 * If this architecture has a "base" platform capability
222483fad1cSNathan Lynch 	 * string, copy it to userspace.
223483fad1cSNathan Lynch 	 */
224483fad1cSNathan Lynch 	u_base_platform = NULL;
225483fad1cSNathan Lynch 	if (k_base_platform) {
226483fad1cSNathan Lynch 		size_t len = strlen(k_base_platform) + 1;
227483fad1cSNathan Lynch 
228483fad1cSNathan Lynch 		u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
229646e84deSAl Viro 		if (copy_to_user(u_base_platform, k_base_platform, len))
230483fad1cSNathan Lynch 			return -EFAULT;
231483fad1cSNathan Lynch 	}
232483fad1cSNathan Lynch 
233f06295b4SKees Cook 	/*
234f06295b4SKees Cook 	 * Generate 16 random bytes for userspace PRNG seeding.
235f06295b4SKees Cook 	 */
236f06295b4SKees Cook 	get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));
237f06295b4SKees Cook 	u_rand_bytes = (elf_addr_t __user *)
238f06295b4SKees Cook 		       STACK_ALLOC(p, sizeof(k_rand_bytes));
239646e84deSAl Viro 	if (copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
240f06295b4SKees Cook 		return -EFAULT;
241f06295b4SKees Cook 
2421da177e4SLinus Torvalds 	/* Create the ELF interpreter info */
24303c6d723SAlexey Dobriyan 	elf_info = (elf_addr_t *)mm->saved_auxv;
2444f9a58d7SOlaf Hering 	/* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
2451da177e4SLinus Torvalds #define NEW_AUX_ENT(id, val) \
246f4e5cc2cSJesper Juhl 	do { \
2471f83d806SAlexey Dobriyan 		*elf_info++ = id; \
2481f83d806SAlexey Dobriyan 		*elf_info++ = val; \
249f4e5cc2cSJesper Juhl 	} while (0)
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds #ifdef ARCH_DLINFO
2521da177e4SLinus Torvalds 	/*
2531da177e4SLinus Torvalds 	 * ARCH_DLINFO must come first so PPC can do its special alignment of
2541da177e4SLinus Torvalds 	 * AUXV.
2554f9a58d7SOlaf Hering 	 * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT() in
2564f9a58d7SOlaf Hering 	 * ARCH_DLINFO changes
2571da177e4SLinus Torvalds 	 */
2581da177e4SLinus Torvalds 	ARCH_DLINFO;
2591da177e4SLinus Torvalds #endif
2601da177e4SLinus Torvalds 	NEW_AUX_ENT(AT_HWCAP, ELF_HWCAP);
2611da177e4SLinus Torvalds 	NEW_AUX_ENT(AT_PAGESZ, ELF_EXEC_PAGESIZE);
2621da177e4SLinus Torvalds 	NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC);
2630da1d500SAkira Kawata 	NEW_AUX_ENT(AT_PHDR, phdr_addr);
2641da177e4SLinus Torvalds 	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
2651da177e4SLinus Torvalds 	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
2661da177e4SLinus Torvalds 	NEW_AUX_ENT(AT_BASE, interp_load_addr);
2672347961bSLaurent Vivier 	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
2682347961bSLaurent Vivier 		flags |= AT_FLAGS_PRESERVE_ARGV0;
2692347961bSLaurent Vivier 	NEW_AUX_ENT(AT_FLAGS, flags);
270a62c5b1bSAlexey Dobriyan 	NEW_AUX_ENT(AT_ENTRY, e_entry);
271ebc887b2SEric W. Biederman 	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
272ebc887b2SEric W. Biederman 	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
273ebc887b2SEric W. Biederman 	NEW_AUX_ENT(AT_GID, from_kgid_munged(cred->user_ns, cred->gid));
274ebc887b2SEric W. Biederman 	NEW_AUX_ENT(AT_EGID, from_kgid_munged(cred->user_ns, cred->egid));
275c425e189SKees Cook 	NEW_AUX_ENT(AT_SECURE, bprm->secureexec);
276f06295b4SKees Cook 	NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes);
2772171364dSMichael Neuling #ifdef ELF_HWCAP2
2782171364dSMichael Neuling 	NEW_AUX_ENT(AT_HWCAP2, ELF_HWCAP2);
2792171364dSMichael Neuling #endif
28065191087SJohn Reiser 	NEW_AUX_ENT(AT_EXECFN, bprm->exec);
2811da177e4SLinus Torvalds 	if (k_platform) {
282f4e5cc2cSJesper Juhl 		NEW_AUX_ENT(AT_PLATFORM,
283f4e5cc2cSJesper Juhl 			    (elf_addr_t)(unsigned long)u_platform);
2841da177e4SLinus Torvalds 	}
285483fad1cSNathan Lynch 	if (k_base_platform) {
286483fad1cSNathan Lynch 		NEW_AUX_ENT(AT_BASE_PLATFORM,
287483fad1cSNathan Lynch 			    (elf_addr_t)(unsigned long)u_base_platform);
288483fad1cSNathan Lynch 	}
289b8a61c9eSEric W. Biederman 	if (bprm->have_execfd) {
290b8a61c9eSEric W. Biederman 		NEW_AUX_ENT(AT_EXECFD, bprm->execfd);
2911da177e4SLinus Torvalds 	}
292317c8194SMathieu Desnoyers #ifdef CONFIG_RSEQ
293317c8194SMathieu Desnoyers 	NEW_AUX_ENT(AT_RSEQ_FEATURE_SIZE, offsetof(struct rseq, end));
294317c8194SMathieu Desnoyers 	NEW_AUX_ENT(AT_RSEQ_ALIGN, __alignof__(struct rseq));
295317c8194SMathieu Desnoyers #endif
2961da177e4SLinus Torvalds #undef NEW_AUX_ENT
2971da177e4SLinus Torvalds 	/* AT_NULL is zero; clear the rest too */
29803c6d723SAlexey Dobriyan 	memset(elf_info, 0, (char *)mm->saved_auxv +
29903c6d723SAlexey Dobriyan 			sizeof(mm->saved_auxv) - (char *)elf_info);
3001da177e4SLinus Torvalds 
3011da177e4SLinus Torvalds 	/* And advance past the AT_NULL entry.  */
3021f83d806SAlexey Dobriyan 	elf_info += 2;
3031da177e4SLinus Torvalds 
30403c6d723SAlexey Dobriyan 	ei_index = elf_info - (elf_addr_t *)mm->saved_auxv;
3051da177e4SLinus Torvalds 	sp = STACK_ADD(p, ei_index);
3061da177e4SLinus Torvalds 
307d20894a2SAndi Kleen 	items = (argc + 1) + (envc + 1) + 1;
3081da177e4SLinus Torvalds 	bprm->p = STACK_ROUND(sp, items);
3091da177e4SLinus Torvalds 
3101da177e4SLinus Torvalds 	/* Point sp at the lowest address on the stack */
3111da177e4SLinus Torvalds #ifdef CONFIG_STACK_GROWSUP
3121da177e4SLinus Torvalds 	sp = (elf_addr_t __user *)bprm->p - items - ei_index;
3131da177e4SLinus Torvalds 	bprm->exec = (unsigned long)sp; /* XXX: PARISC HACK */
3141da177e4SLinus Torvalds #else
3151da177e4SLinus Torvalds 	sp = (elf_addr_t __user *)bprm->p;
3161da177e4SLinus Torvalds #endif
3171da177e4SLinus Torvalds 
318b6a2fea3SOllie Wild 
319b6a2fea3SOllie Wild 	/*
320b6a2fea3SOllie Wild 	 * Grow the stack manually; some architectures have a limit on how
321b6a2fea3SOllie Wild 	 * far ahead a user-space access may be in order to grow the stack.
322b6a2fea3SOllie Wild 	 */
323f440fa1aSLiam R. Howlett 	if (mmap_write_lock_killable(mm))
324b2767d97SJann Horn 		return -EINTR;
3258d7071afSLinus Torvalds 	vma = find_extend_vma_locked(mm, bprm->p);
326f440fa1aSLiam R. Howlett 	mmap_write_unlock(mm);
327b6a2fea3SOllie Wild 	if (!vma)
328b6a2fea3SOllie Wild 		return -EFAULT;
329b6a2fea3SOllie Wild 
3301da177e4SLinus Torvalds 	/* Now, let's put argc (and argv, envp if appropriate) on the stack */
331646e84deSAl Viro 	if (put_user(argc, sp++))
3321da177e4SLinus Torvalds 		return -EFAULT;
3331da177e4SLinus Torvalds 
33467c6777aSKees Cook 	/* Populate list of argv pointers back to argv strings. */
33503c6d723SAlexey Dobriyan 	p = mm->arg_end = mm->arg_start;
3361da177e4SLinus Torvalds 	while (argc-- > 0) {
3371da177e4SLinus Torvalds 		size_t len;
338646e84deSAl Viro 		if (put_user((elf_addr_t)p, sp++))
339841d5fb7SHeiko Carstens 			return -EFAULT;
340b6a2fea3SOllie Wild 		len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);
341b6a2fea3SOllie Wild 		if (!len || len > MAX_ARG_STRLEN)
34223c4971eSWANG Cong 			return -EINVAL;
3431da177e4SLinus Torvalds 		p += len;
3441da177e4SLinus Torvalds 	}
345646e84deSAl Viro 	if (put_user(0, sp++))
3461da177e4SLinus Torvalds 		return -EFAULT;
34703c6d723SAlexey Dobriyan 	mm->arg_end = p;
34867c6777aSKees Cook 
34967c6777aSKees Cook 	/* Populate list of envp pointers back to envp strings. */
35003c6d723SAlexey Dobriyan 	mm->env_end = mm->env_start = p;
3511da177e4SLinus Torvalds 	while (envc-- > 0) {
3521da177e4SLinus Torvalds 		size_t len;
353646e84deSAl Viro 		if (put_user((elf_addr_t)p, sp++))
354841d5fb7SHeiko Carstens 			return -EFAULT;
355b6a2fea3SOllie Wild 		len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);
356b6a2fea3SOllie Wild 		if (!len || len > MAX_ARG_STRLEN)
35723c4971eSWANG Cong 			return -EINVAL;
3581da177e4SLinus Torvalds 		p += len;
3591da177e4SLinus Torvalds 	}
360646e84deSAl Viro 	if (put_user(0, sp++))
3611da177e4SLinus Torvalds 		return -EFAULT;
36203c6d723SAlexey Dobriyan 	mm->env_end = p;
3631da177e4SLinus Torvalds 
3641da177e4SLinus Torvalds 	/* Put the elf_info on the stack in the right place.  */
36503c6d723SAlexey Dobriyan 	if (copy_to_user(sp, mm->saved_auxv, ei_index * sizeof(elf_addr_t)))
3661da177e4SLinus Torvalds 		return -EFAULT;
3671da177e4SLinus Torvalds 	return 0;
3681da177e4SLinus Torvalds }
3691da177e4SLinus Torvalds 
elf_map(struct file * filep,unsigned long addr,const struct elf_phdr * eppnt,int prot,int type,unsigned long total_size)3701da177e4SLinus Torvalds static unsigned long elf_map(struct file *filep, unsigned long addr,
37149ac9819SAlexey Dobriyan 		const struct elf_phdr *eppnt, int prot, int type,
372cc503c1bSJiri Kosina 		unsigned long total_size)
3731da177e4SLinus Torvalds {
3741da177e4SLinus Torvalds 	unsigned long map_addr;
375cc503c1bSJiri Kosina 	unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
376cc503c1bSJiri Kosina 	unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
377cc503c1bSJiri Kosina 	addr = ELF_PAGESTART(addr);
378cc503c1bSJiri Kosina 	size = ELF_PAGEALIGN(size);
37960bfba7eSJan Kratochvil 
380d4e3cc38SAndrew Morton 	/* mmap() will return -EINVAL if given a zero size, but a
381d4e3cc38SAndrew Morton 	 * segment with zero filesize is perfectly valid */
382cc503c1bSJiri Kosina 	if (!size)
383cc503c1bSJiri Kosina 		return addr;
384cc503c1bSJiri Kosina 
385cc503c1bSJiri Kosina 	/*
386cc503c1bSJiri Kosina 	* total_size is the size of the ELF (interpreter) image.
387cc503c1bSJiri Kosina 	* The _first_ mmap needs to know the full size, otherwise
388cc503c1bSJiri Kosina 	* randomization might put this image into an overlapping
389cc503c1bSJiri Kosina 	* position with the ELF binary image. (since size < total_size)
390cc503c1bSJiri Kosina 	* So we first map the 'big' image - and unmap the remainder at
391cc503c1bSJiri Kosina 	* the end. (which unmap is needed for ELF images with holes.)
392cc503c1bSJiri Kosina 	*/
393cc503c1bSJiri Kosina 	if (total_size) {
394cc503c1bSJiri Kosina 		total_size = ELF_PAGEALIGN(total_size);
3955a5e4c2eSAl Viro 		map_addr = vm_mmap(filep, addr, total_size, prot, type, off);
396cc503c1bSJiri Kosina 		if (!BAD_ADDR(map_addr))
3975a5e4c2eSAl Viro 			vm_munmap(map_addr+size, total_size-size);
398cc503c1bSJiri Kosina 	} else
3995a5e4c2eSAl Viro 		map_addr = vm_mmap(filep, addr, size, prot, type, off);
400cc503c1bSJiri Kosina 
401d23a61eeSTetsuo Handa 	if ((type & MAP_FIXED_NOREPLACE) &&
402d23a61eeSTetsuo Handa 	    PTR_ERR((void *)map_addr) == -EEXIST)
403d23a61eeSTetsuo Handa 		pr_info("%d (%s): Uhuuh, elf segment at %px requested but the memory is mapped already\n",
404d23a61eeSTetsuo Handa 			task_pid_nr(current), current->comm, (void *)addr);
4054ed28639SMichal Hocko 
4061da177e4SLinus Torvalds 	return(map_addr);
4071da177e4SLinus Torvalds }
4081da177e4SLinus Torvalds 
total_mapping_size(const struct elf_phdr * phdr,int nr)40910b19249SAlexey Dobriyan static unsigned long total_mapping_size(const struct elf_phdr *phdr, int nr)
410cc503c1bSJiri Kosina {
41110b19249SAlexey Dobriyan 	elf_addr_t min_addr = -1;
41210b19249SAlexey Dobriyan 	elf_addr_t max_addr = 0;
41310b19249SAlexey Dobriyan 	bool pt_load = false;
41410b19249SAlexey Dobriyan 	int i;
415cc503c1bSJiri Kosina 
416cc503c1bSJiri Kosina 	for (i = 0; i < nr; i++) {
41710b19249SAlexey Dobriyan 		if (phdr[i].p_type == PT_LOAD) {
41810b19249SAlexey Dobriyan 			min_addr = min(min_addr, ELF_PAGESTART(phdr[i].p_vaddr));
41910b19249SAlexey Dobriyan 			max_addr = max(max_addr, phdr[i].p_vaddr + phdr[i].p_memsz);
42010b19249SAlexey Dobriyan 			pt_load = true;
421cc503c1bSJiri Kosina 		}
422cc503c1bSJiri Kosina 	}
42310b19249SAlexey Dobriyan 	return pt_load ? (max_addr - min_addr) : 0;
424cc503c1bSJiri Kosina }
425cc503c1bSJiri Kosina 
elf_read(struct file * file,void * buf,size_t len,loff_t pos)426658c0335SAlexey Dobriyan static int elf_read(struct file *file, void *buf, size_t len, loff_t pos)
427658c0335SAlexey Dobriyan {
428658c0335SAlexey Dobriyan 	ssize_t rv;
429658c0335SAlexey Dobriyan 
430658c0335SAlexey Dobriyan 	rv = kernel_read(file, buf, len, &pos);
431658c0335SAlexey Dobriyan 	if (unlikely(rv != len)) {
432658c0335SAlexey Dobriyan 		return (rv < 0) ? rv : -EIO;
433658c0335SAlexey Dobriyan 	}
434658c0335SAlexey Dobriyan 	return 0;
435658c0335SAlexey Dobriyan }
436658c0335SAlexey Dobriyan 
maximum_alignment(struct elf_phdr * cmds,int nr)437ce81bb25SChris Kennelly static unsigned long maximum_alignment(struct elf_phdr *cmds, int nr)
438ce81bb25SChris Kennelly {
439ce81bb25SChris Kennelly 	unsigned long alignment = 0;
440ce81bb25SChris Kennelly 	int i;
441ce81bb25SChris Kennelly 
442ce81bb25SChris Kennelly 	for (i = 0; i < nr; i++) {
443ce81bb25SChris Kennelly 		if (cmds[i].p_type == PT_LOAD) {
444ce81bb25SChris Kennelly 			unsigned long p_align = cmds[i].p_align;
445ce81bb25SChris Kennelly 
446ce81bb25SChris Kennelly 			/* skip non-power of two alignments as invalid */
447ce81bb25SChris Kennelly 			if (!is_power_of_2(p_align))
448ce81bb25SChris Kennelly 				continue;
449ce81bb25SChris Kennelly 			alignment = max(alignment, p_align);
450ce81bb25SChris Kennelly 		}
451ce81bb25SChris Kennelly 	}
452ce81bb25SChris Kennelly 
453ce81bb25SChris Kennelly 	/* ensure we align to at least one page */
454ce81bb25SChris Kennelly 	return ELF_PAGEALIGN(alignment);
455ce81bb25SChris Kennelly }
456ce81bb25SChris Kennelly 
4576a8d3894SPaul Burton /**
4586a8d3894SPaul Burton  * load_elf_phdrs() - load ELF program headers
4596a8d3894SPaul Burton  * @elf_ex:   ELF header of the binary whose program headers should be loaded
4606a8d3894SPaul Burton  * @elf_file: the opened ELF binary file
4616a8d3894SPaul Burton  *
4626a8d3894SPaul Burton  * Loads ELF program headers from the binary file elf_file, which has the ELF
4636a8d3894SPaul Burton  * header pointed to by elf_ex, into a newly allocated array. The caller is
464cfc46ca4SRolf Eike Beer  * responsible for freeing the allocated data. Returns NULL upon failure.
4656a8d3894SPaul Burton  */
load_elf_phdrs(const struct elfhdr * elf_ex,struct file * elf_file)46649ac9819SAlexey Dobriyan static struct elf_phdr *load_elf_phdrs(const struct elfhdr *elf_ex,
4676a8d3894SPaul Burton 				       struct file *elf_file)
4686a8d3894SPaul Burton {
4696a8d3894SPaul Burton 	struct elf_phdr *elf_phdata = NULL;
470ef20c513SRolf Eike Beer 	int retval = -1;
471faf1c315SAlexey Dobriyan 	unsigned int size;
4726a8d3894SPaul Burton 
4736a8d3894SPaul Burton 	/*
4746a8d3894SPaul Burton 	 * If the size of this structure has changed, then punt, since
4756a8d3894SPaul Burton 	 * we will be doing the wrong thing.
4766a8d3894SPaul Burton 	 */
4776a8d3894SPaul Burton 	if (elf_ex->e_phentsize != sizeof(struct elf_phdr))
4786a8d3894SPaul Burton 		goto out;
4796a8d3894SPaul Burton 
4806a8d3894SPaul Burton 	/* Sanity check the number of program headers... */
4816a8d3894SPaul Burton 	/* ...and their total size. */
4826a8d3894SPaul Burton 	size = sizeof(struct elf_phdr) * elf_ex->e_phnum;
483faf1c315SAlexey Dobriyan 	if (size == 0 || size > 65536 || size > ELF_MIN_ALIGN)
4846a8d3894SPaul Burton 		goto out;
4856a8d3894SPaul Burton 
4866a8d3894SPaul Burton 	elf_phdata = kmalloc(size, GFP_KERNEL);
4876a8d3894SPaul Burton 	if (!elf_phdata)
4886a8d3894SPaul Burton 		goto out;
4896a8d3894SPaul Burton 
4906a8d3894SPaul Burton 	/* Read in the program headers */
491658c0335SAlexey Dobriyan 	retval = elf_read(elf_file, elf_phdata, size, elf_ex->e_phoff);
4926a8d3894SPaul Burton 
4936a8d3894SPaul Burton out:
494ef20c513SRolf Eike Beer 	if (retval) {
4956a8d3894SPaul Burton 		kfree(elf_phdata);
4966a8d3894SPaul Burton 		elf_phdata = NULL;
4976a8d3894SPaul Burton 	}
4986a8d3894SPaul Burton 	return elf_phdata;
4996a8d3894SPaul Burton }
500cc503c1bSJiri Kosina 
501774c105eSPaul Burton #ifndef CONFIG_ARCH_BINFMT_ELF_STATE
502774c105eSPaul Burton 
503774c105eSPaul Burton /**
504774c105eSPaul Burton  * struct arch_elf_state - arch-specific ELF loading state
505774c105eSPaul Burton  *
506774c105eSPaul Burton  * This structure is used to preserve architecture specific data during
507774c105eSPaul Burton  * the loading of an ELF file, throughout the checking of architecture
508774c105eSPaul Burton  * specific ELF headers & through to the point where the ELF load is
509774c105eSPaul Burton  * known to be proceeding (ie. SET_PERSONALITY).
510774c105eSPaul Burton  *
511774c105eSPaul Burton  * This implementation is a dummy for architectures which require no
512774c105eSPaul Burton  * specific state.
513774c105eSPaul Burton  */
514774c105eSPaul Burton struct arch_elf_state {
515774c105eSPaul Burton };
516774c105eSPaul Burton 
517774c105eSPaul Burton #define INIT_ARCH_ELF_STATE {}
518774c105eSPaul Burton 
519774c105eSPaul Burton /**
520774c105eSPaul Burton  * arch_elf_pt_proc() - check a PT_LOPROC..PT_HIPROC ELF program header
521774c105eSPaul Burton  * @ehdr:	The main ELF header
522774c105eSPaul Burton  * @phdr:	The program header to check
523774c105eSPaul Burton  * @elf:	The open ELF file
524774c105eSPaul Burton  * @is_interp:	True if the phdr is from the interpreter of the ELF being
525774c105eSPaul Burton  *		loaded, else false.
526774c105eSPaul Burton  * @state:	Architecture-specific state preserved throughout the process
527774c105eSPaul Burton  *		of loading the ELF.
528774c105eSPaul Burton  *
529774c105eSPaul Burton  * Inspects the program header phdr to validate its correctness and/or
530774c105eSPaul Burton  * suitability for the system. Called once per ELF program header in the
531774c105eSPaul Burton  * range PT_LOPROC to PT_HIPROC, for both the ELF being loaded and its
532774c105eSPaul Burton  * interpreter.
533774c105eSPaul Burton  *
534774c105eSPaul Burton  * Return: Zero to proceed with the ELF load, non-zero to fail the ELF load
535774c105eSPaul Burton  *         with that return code.
536774c105eSPaul Burton  */
arch_elf_pt_proc(struct elfhdr * ehdr,struct elf_phdr * phdr,struct file * elf,bool is_interp,struct arch_elf_state * state)537774c105eSPaul Burton static inline int arch_elf_pt_proc(struct elfhdr *ehdr,
538774c105eSPaul Burton 				   struct elf_phdr *phdr,
539774c105eSPaul Burton 				   struct file *elf, bool is_interp,
540774c105eSPaul Burton 				   struct arch_elf_state *state)
541774c105eSPaul Burton {
542774c105eSPaul Burton 	/* Dummy implementation, always proceed */
543774c105eSPaul Burton 	return 0;
544774c105eSPaul Burton }
545774c105eSPaul Burton 
546774c105eSPaul Burton /**
54754d15714SMaciej W. Rozycki  * arch_check_elf() - check an ELF executable
548774c105eSPaul Burton  * @ehdr:	The main ELF header
549774c105eSPaul Burton  * @has_interp:	True if the ELF has an interpreter, else false.
550eb4bc076SMaciej W. Rozycki  * @interp_ehdr: The interpreter's ELF header
551774c105eSPaul Burton  * @state:	Architecture-specific state preserved throughout the process
552774c105eSPaul Burton  *		of loading the ELF.
553774c105eSPaul Burton  *
554774c105eSPaul Burton  * Provides a final opportunity for architecture code to reject the loading
555774c105eSPaul Burton  * of the ELF & cause an exec syscall to return an error. This is called after
556774c105eSPaul Burton  * all program headers to be checked by arch_elf_pt_proc have been.
557774c105eSPaul Burton  *
558774c105eSPaul Burton  * Return: Zero to proceed with the ELF load, non-zero to fail the ELF load
559774c105eSPaul Burton  *         with that return code.
560774c105eSPaul Burton  */
arch_check_elf(struct elfhdr * ehdr,bool has_interp,struct elfhdr * interp_ehdr,struct arch_elf_state * state)561774c105eSPaul Burton static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp,
562eb4bc076SMaciej W. Rozycki 				 struct elfhdr *interp_ehdr,
563774c105eSPaul Burton 				 struct arch_elf_state *state)
564774c105eSPaul Burton {
565774c105eSPaul Burton 	/* Dummy implementation, always proceed */
566774c105eSPaul Burton 	return 0;
567774c105eSPaul Burton }
568774c105eSPaul Burton 
569774c105eSPaul Burton #endif /* !CONFIG_ARCH_BINFMT_ELF_STATE */
5701da177e4SLinus Torvalds 
make_prot(u32 p_flags,struct arch_elf_state * arch_state,bool has_interp,bool is_interp)571fe0f6766SDave Martin static inline int make_prot(u32 p_flags, struct arch_elf_state *arch_state,
572fe0f6766SDave Martin 			    bool has_interp, bool is_interp)
573d8e7cb39SAlexey Dobriyan {
574d8e7cb39SAlexey Dobriyan 	int prot = 0;
575d8e7cb39SAlexey Dobriyan 
576d8e7cb39SAlexey Dobriyan 	if (p_flags & PF_R)
577d8e7cb39SAlexey Dobriyan 		prot |= PROT_READ;
578d8e7cb39SAlexey Dobriyan 	if (p_flags & PF_W)
579d8e7cb39SAlexey Dobriyan 		prot |= PROT_WRITE;
580d8e7cb39SAlexey Dobriyan 	if (p_flags & PF_X)
581d8e7cb39SAlexey Dobriyan 		prot |= PROT_EXEC;
582fe0f6766SDave Martin 
583fe0f6766SDave Martin 	return arch_elf_adjust_prot(prot, arch_state, has_interp, is_interp);
584d8e7cb39SAlexey Dobriyan }
585d8e7cb39SAlexey Dobriyan 
5861da177e4SLinus Torvalds /* This is much more generalized than the library routine read function,
5871da177e4SLinus Torvalds    so we keep this separate.  Technically the library read function
5881da177e4SLinus Torvalds    is only provided so that we can read a.out libraries that have
5891da177e4SLinus Torvalds    an ELF header */
5901da177e4SLinus Torvalds 
load_elf_interp(struct elfhdr * interp_elf_ex,struct file * interpreter,unsigned long no_base,struct elf_phdr * interp_elf_phdata,struct arch_elf_state * arch_state)5911da177e4SLinus Torvalds static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
59281696d5dSAlexey Dobriyan 		struct file *interpreter,
593fe0f6766SDave Martin 		unsigned long no_base, struct elf_phdr *interp_elf_phdata,
594fe0f6766SDave Martin 		struct arch_elf_state *arch_state)
5951da177e4SLinus Torvalds {
5961da177e4SLinus Torvalds 	struct elf_phdr *eppnt;
5971da177e4SLinus Torvalds 	unsigned long load_addr = 0;
5981da177e4SLinus Torvalds 	int load_addr_set = 0;
5991da177e4SLinus Torvalds 	unsigned long last_bss = 0, elf_bss = 0;
60016e72e9bSDenys Vlasenko 	int bss_prot = 0;
6011da177e4SLinus Torvalds 	unsigned long error = ~0UL;
602cc503c1bSJiri Kosina 	unsigned long total_size;
6036a8d3894SPaul Burton 	int i;
6041da177e4SLinus Torvalds 
6051da177e4SLinus Torvalds 	/* First of all, some simple consistency checks */
6061da177e4SLinus Torvalds 	if (interp_elf_ex->e_type != ET_EXEC &&
6071da177e4SLinus Torvalds 	    interp_elf_ex->e_type != ET_DYN)
6081da177e4SLinus Torvalds 		goto out;
6094755200bSNicolas Pitre 	if (!elf_check_arch(interp_elf_ex) ||
6104755200bSNicolas Pitre 	    elf_check_fdpic(interp_elf_ex))
6111da177e4SLinus Torvalds 		goto out;
61272c2d531SAl Viro 	if (!interpreter->f_op->mmap)
6131da177e4SLinus Torvalds 		goto out;
6141da177e4SLinus Torvalds 
615a9d9ef13SPaul Burton 	total_size = total_mapping_size(interp_elf_phdata,
616a9d9ef13SPaul Burton 					interp_elf_ex->e_phnum);
617cc503c1bSJiri Kosina 	if (!total_size) {
618cc503c1bSJiri Kosina 		error = -EINVAL;
619a9d9ef13SPaul Burton 		goto out;
620cc503c1bSJiri Kosina 	}
621cc503c1bSJiri Kosina 
622a9d9ef13SPaul Burton 	eppnt = interp_elf_phdata;
6231da177e4SLinus Torvalds 	for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
6241da177e4SLinus Torvalds 		if (eppnt->p_type == PT_LOAD) {
6254589ff7cSDavid Hildenbrand 			int elf_type = MAP_PRIVATE;
626fe0f6766SDave Martin 			int elf_prot = make_prot(eppnt->p_flags, arch_state,
627fe0f6766SDave Martin 						 true, true);
6281da177e4SLinus Torvalds 			unsigned long vaddr = 0;
6291da177e4SLinus Torvalds 			unsigned long k, map_addr;
6301da177e4SLinus Torvalds 
6311da177e4SLinus Torvalds 			vaddr = eppnt->p_vaddr;
6321da177e4SLinus Torvalds 			if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
6339b2f72ccSChen Jingwen 				elf_type |= MAP_FIXED;
634cc503c1bSJiri Kosina 			else if (no_base && interp_elf_ex->e_type == ET_DYN)
635cc503c1bSJiri Kosina 				load_addr = -vaddr;
6361da177e4SLinus Torvalds 
637f4e5cc2cSJesper Juhl 			map_addr = elf_map(interpreter, load_addr + vaddr,
638cc503c1bSJiri Kosina 					eppnt, elf_prot, elf_type, total_size);
639cc503c1bSJiri Kosina 			total_size = 0;
6401da177e4SLinus Torvalds 			error = map_addr;
6411da177e4SLinus Torvalds 			if (BAD_ADDR(map_addr))
642a9d9ef13SPaul Burton 				goto out;
6431da177e4SLinus Torvalds 
644f4e5cc2cSJesper Juhl 			if (!load_addr_set &&
645f4e5cc2cSJesper Juhl 			    interp_elf_ex->e_type == ET_DYN) {
6461da177e4SLinus Torvalds 				load_addr = map_addr - ELF_PAGESTART(vaddr);
6471da177e4SLinus Torvalds 				load_addr_set = 1;
6481da177e4SLinus Torvalds 			}
6491da177e4SLinus Torvalds 
6501da177e4SLinus Torvalds 			/*
6511da177e4SLinus Torvalds 			 * Check to see if the section's size will overflow the
6521da177e4SLinus Torvalds 			 * allowed task size. Note that p_filesz must always be
653f4e5cc2cSJesper Juhl 			 * <= p_memsize so it's only necessary to check p_memsz.
6541da177e4SLinus Torvalds 			 */
6551da177e4SLinus Torvalds 			k = load_addr + eppnt->p_vaddr;
656ce51059bSChuck Ebbert 			if (BAD_ADDR(k) ||
657f4e5cc2cSJesper Juhl 			    eppnt->p_filesz > eppnt->p_memsz ||
658f4e5cc2cSJesper Juhl 			    eppnt->p_memsz > TASK_SIZE ||
659f4e5cc2cSJesper Juhl 			    TASK_SIZE - eppnt->p_memsz < k) {
6601da177e4SLinus Torvalds 				error = -ENOMEM;
661a9d9ef13SPaul Burton 				goto out;
6621da177e4SLinus Torvalds 			}
6631da177e4SLinus Torvalds 
6641da177e4SLinus Torvalds 			/*
665f4e5cc2cSJesper Juhl 			 * Find the end of the file mapping for this phdr, and
666f4e5cc2cSJesper Juhl 			 * keep track of the largest address we see for this.
6671da177e4SLinus Torvalds 			 */
6681da177e4SLinus Torvalds 			k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
6691da177e4SLinus Torvalds 			if (k > elf_bss)
6701da177e4SLinus Torvalds 				elf_bss = k;
6711da177e4SLinus Torvalds 
6721da177e4SLinus Torvalds 			/*
6731da177e4SLinus Torvalds 			 * Do the same thing for the memory mapping - between
6741da177e4SLinus Torvalds 			 * elf_bss and last_bss is the bss section.
6751da177e4SLinus Torvalds 			 */
6760036d1f7SKees Cook 			k = load_addr + eppnt->p_vaddr + eppnt->p_memsz;
67716e72e9bSDenys Vlasenko 			if (k > last_bss) {
6781da177e4SLinus Torvalds 				last_bss = k;
67916e72e9bSDenys Vlasenko 				bss_prot = elf_prot;
68016e72e9bSDenys Vlasenko 			}
6811da177e4SLinus Torvalds 		}
6821da177e4SLinus Torvalds 	}
6831da177e4SLinus Torvalds 
6841da177e4SLinus Torvalds 	/*
6850036d1f7SKees Cook 	 * Now fill out the bss section: first pad the last page from
6860036d1f7SKees Cook 	 * the file up to the page boundary, and zero it from elf_bss
6870036d1f7SKees Cook 	 * up to the end of the page.
6881da177e4SLinus Torvalds 	 */
6891da177e4SLinus Torvalds 	if (padzero(elf_bss)) {
6901da177e4SLinus Torvalds 		error = -EFAULT;
691a9d9ef13SPaul Burton 		goto out;
6921da177e4SLinus Torvalds 	}
6930036d1f7SKees Cook 	/*
6940036d1f7SKees Cook 	 * Next, align both the file and mem bss up to the page size,
6950036d1f7SKees Cook 	 * since this is where elf_bss was just zeroed up to, and where
69616e72e9bSDenys Vlasenko 	 * last_bss will end after the vm_brk_flags() below.
6970036d1f7SKees Cook 	 */
6980036d1f7SKees Cook 	elf_bss = ELF_PAGEALIGN(elf_bss);
6990036d1f7SKees Cook 	last_bss = ELF_PAGEALIGN(last_bss);
7000036d1f7SKees Cook 	/* Finally, if there is still more bss to allocate, do it. */
7010036d1f7SKees Cook 	if (last_bss > elf_bss) {
70216e72e9bSDenys Vlasenko 		error = vm_brk_flags(elf_bss, last_bss - elf_bss,
70316e72e9bSDenys Vlasenko 				bss_prot & PROT_EXEC ? VM_EXEC : 0);
7045d22fc25SLinus Torvalds 		if (error)
705a9d9ef13SPaul Burton 			goto out;
7061da177e4SLinus Torvalds 	}
7071da177e4SLinus Torvalds 
708cc503c1bSJiri Kosina 	error = load_addr;
7091da177e4SLinus Torvalds out:
7101da177e4SLinus Torvalds 	return error;
7111da177e4SLinus Torvalds }
7121da177e4SLinus Torvalds 
7131da177e4SLinus Torvalds /*
7141da177e4SLinus Torvalds  * These are the functions used to load ELF style executables and shared
7151da177e4SLinus Torvalds  * libraries.  There is no binary dependent code anywhere else.
7161da177e4SLinus Torvalds  */
7171da177e4SLinus Torvalds 
parse_elf_property(const char * data,size_t * off,size_t datasz,struct arch_elf_state * arch,bool have_prev_type,u32 * prev_type)71800e19ceeSDave Martin static int parse_elf_property(const char *data, size_t *off, size_t datasz,
71900e19ceeSDave Martin 			      struct arch_elf_state *arch,
72000e19ceeSDave Martin 			      bool have_prev_type, u32 *prev_type)
72100e19ceeSDave Martin {
72200e19ceeSDave Martin 	size_t o, step;
72300e19ceeSDave Martin 	const struct gnu_property *pr;
72400e19ceeSDave Martin 	int ret;
72500e19ceeSDave Martin 
72600e19ceeSDave Martin 	if (*off == datasz)
72700e19ceeSDave Martin 		return -ENOENT;
72800e19ceeSDave Martin 
72900e19ceeSDave Martin 	if (WARN_ON_ONCE(*off > datasz || *off % ELF_GNU_PROPERTY_ALIGN))
73000e19ceeSDave Martin 		return -EIO;
73100e19ceeSDave Martin 	o = *off;
73200e19ceeSDave Martin 	datasz -= *off;
73300e19ceeSDave Martin 
73400e19ceeSDave Martin 	if (datasz < sizeof(*pr))
73500e19ceeSDave Martin 		return -ENOEXEC;
73600e19ceeSDave Martin 	pr = (const struct gnu_property *)(data + o);
73700e19ceeSDave Martin 	o += sizeof(*pr);
73800e19ceeSDave Martin 	datasz -= sizeof(*pr);
73900e19ceeSDave Martin 
74000e19ceeSDave Martin 	if (pr->pr_datasz > datasz)
74100e19ceeSDave Martin 		return -ENOEXEC;
74200e19ceeSDave Martin 
74300e19ceeSDave Martin 	WARN_ON_ONCE(o % ELF_GNU_PROPERTY_ALIGN);
74400e19ceeSDave Martin 	step = round_up(pr->pr_datasz, ELF_GNU_PROPERTY_ALIGN);
74500e19ceeSDave Martin 	if (step > datasz)
74600e19ceeSDave Martin 		return -ENOEXEC;
74700e19ceeSDave Martin 
74800e19ceeSDave Martin 	/* Properties are supposed to be unique and sorted on pr_type: */
74900e19ceeSDave Martin 	if (have_prev_type && pr->pr_type <= *prev_type)
75000e19ceeSDave Martin 		return -ENOEXEC;
75100e19ceeSDave Martin 	*prev_type = pr->pr_type;
75200e19ceeSDave Martin 
75300e19ceeSDave Martin 	ret = arch_parse_elf_property(pr->pr_type, data + o,
75400e19ceeSDave Martin 				      pr->pr_datasz, ELF_COMPAT, arch);
75500e19ceeSDave Martin 	if (ret)
75600e19ceeSDave Martin 		return ret;
75700e19ceeSDave Martin 
75800e19ceeSDave Martin 	*off = o + step;
75900e19ceeSDave Martin 	return 0;
76000e19ceeSDave Martin }
76100e19ceeSDave Martin 
76200e19ceeSDave Martin #define NOTE_DATA_SZ SZ_1K
76300e19ceeSDave Martin #define GNU_PROPERTY_TYPE_0_NAME "GNU"
76400e19ceeSDave Martin #define NOTE_NAME_SZ (sizeof(GNU_PROPERTY_TYPE_0_NAME))
76500e19ceeSDave Martin 
parse_elf_properties(struct file * f,const struct elf_phdr * phdr,struct arch_elf_state * arch)76600e19ceeSDave Martin static int parse_elf_properties(struct file *f, const struct elf_phdr *phdr,
76700e19ceeSDave Martin 				struct arch_elf_state *arch)
76800e19ceeSDave Martin {
76900e19ceeSDave Martin 	union {
77000e19ceeSDave Martin 		struct elf_note nhdr;
77100e19ceeSDave Martin 		char data[NOTE_DATA_SZ];
77200e19ceeSDave Martin 	} note;
77300e19ceeSDave Martin 	loff_t pos;
77400e19ceeSDave Martin 	ssize_t n;
77500e19ceeSDave Martin 	size_t off, datasz;
77600e19ceeSDave Martin 	int ret;
77700e19ceeSDave Martin 	bool have_prev_type;
77800e19ceeSDave Martin 	u32 prev_type;
77900e19ceeSDave Martin 
78000e19ceeSDave Martin 	if (!IS_ENABLED(CONFIG_ARCH_USE_GNU_PROPERTY) || !phdr)
78100e19ceeSDave Martin 		return 0;
78200e19ceeSDave Martin 
78300e19ceeSDave Martin 	/* load_elf_binary() shouldn't call us unless this is true... */
78400e19ceeSDave Martin 	if (WARN_ON_ONCE(phdr->p_type != PT_GNU_PROPERTY))
78500e19ceeSDave Martin 		return -ENOEXEC;
78600e19ceeSDave Martin 
78700e19ceeSDave Martin 	/* If the properties are crazy large, that's too bad (for now): */
78800e19ceeSDave Martin 	if (phdr->p_filesz > sizeof(note))
78900e19ceeSDave Martin 		return -ENOEXEC;
79000e19ceeSDave Martin 
79100e19ceeSDave Martin 	pos = phdr->p_offset;
79200e19ceeSDave Martin 	n = kernel_read(f, &note, phdr->p_filesz, &pos);
79300e19ceeSDave Martin 
79400e19ceeSDave Martin 	BUILD_BUG_ON(sizeof(note) < sizeof(note.nhdr) + NOTE_NAME_SZ);
79500e19ceeSDave Martin 	if (n < 0 || n < sizeof(note.nhdr) + NOTE_NAME_SZ)
79600e19ceeSDave Martin 		return -EIO;
79700e19ceeSDave Martin 
79800e19ceeSDave Martin 	if (note.nhdr.n_type != NT_GNU_PROPERTY_TYPE_0 ||
79900e19ceeSDave Martin 	    note.nhdr.n_namesz != NOTE_NAME_SZ ||
80000e19ceeSDave Martin 	    strncmp(note.data + sizeof(note.nhdr),
80100e19ceeSDave Martin 		    GNU_PROPERTY_TYPE_0_NAME, n - sizeof(note.nhdr)))
80200e19ceeSDave Martin 		return -ENOEXEC;
80300e19ceeSDave Martin 
80400e19ceeSDave Martin 	off = round_up(sizeof(note.nhdr) + NOTE_NAME_SZ,
80500e19ceeSDave Martin 		       ELF_GNU_PROPERTY_ALIGN);
80600e19ceeSDave Martin 	if (off > n)
80700e19ceeSDave Martin 		return -ENOEXEC;
80800e19ceeSDave Martin 
80900e19ceeSDave Martin 	if (note.nhdr.n_descsz > n - off)
81000e19ceeSDave Martin 		return -ENOEXEC;
81100e19ceeSDave Martin 	datasz = off + note.nhdr.n_descsz;
81200e19ceeSDave Martin 
81300e19ceeSDave Martin 	have_prev_type = false;
81400e19ceeSDave Martin 	do {
81500e19ceeSDave Martin 		ret = parse_elf_property(note.data, &off, datasz, arch,
81600e19ceeSDave Martin 					 have_prev_type, &prev_type);
81700e19ceeSDave Martin 		have_prev_type = true;
81800e19ceeSDave Martin 	} while (!ret);
81900e19ceeSDave Martin 
82000e19ceeSDave Martin 	return ret == -ENOENT ? 0 : ret;
82100e19ceeSDave Martin }
82200e19ceeSDave Martin 
load_elf_binary(struct linux_binprm * bprm)82371613c3bSAl Viro static int load_elf_binary(struct linux_binprm *bprm)
8241da177e4SLinus Torvalds {
8251da177e4SLinus Torvalds 	struct file *interpreter = NULL; /* to shut gcc up */
8262b4bfbe0SAkira Kawata 	unsigned long load_bias = 0, phdr_addr = 0;
8272b4bfbe0SAkira Kawata 	int first_pt_load = 1;
8281da177e4SLinus Torvalds 	unsigned long error;
829a9d9ef13SPaul Burton 	struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL;
83000e19ceeSDave Martin 	struct elf_phdr *elf_property_phdata = NULL;
8311da177e4SLinus Torvalds 	unsigned long elf_bss, elf_brk;
83216e72e9bSDenys Vlasenko 	int bss_prot = 0;
8331da177e4SLinus Torvalds 	int retval, i;
834cc503c1bSJiri Kosina 	unsigned long elf_entry;
835a62c5b1bSAlexey Dobriyan 	unsigned long e_entry;
836cc503c1bSJiri Kosina 	unsigned long interp_load_addr = 0;
8371da177e4SLinus Torvalds 	unsigned long start_code, end_code, start_data, end_data;
8381a530a6fSDavid Daney 	unsigned long reloc_func_desc __maybe_unused = 0;
8398de61e69SDavid Rientjes 	int executable_stack = EXSTACK_DEFAULT;
840a62c5b1bSAlexey Dobriyan 	struct elfhdr *elf_ex = (struct elfhdr *)bprm->buf;
8410693ffebSAlexey Dobriyan 	struct elfhdr *interp_elf_ex = NULL;
842774c105eSPaul Burton 	struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE;
84303c6d723SAlexey Dobriyan 	struct mm_struct *mm;
844249b08e4SAlexey Dobriyan 	struct pt_regs *regs;
8451da177e4SLinus Torvalds 
8461da177e4SLinus Torvalds 	retval = -ENOEXEC;
8471da177e4SLinus Torvalds 	/* First of all, some simple consistency checks */
848a62c5b1bSAlexey Dobriyan 	if (memcmp(elf_ex->e_ident, ELFMAG, SELFMAG) != 0)
8491da177e4SLinus Torvalds 		goto out;
8501da177e4SLinus Torvalds 
851a62c5b1bSAlexey Dobriyan 	if (elf_ex->e_type != ET_EXEC && elf_ex->e_type != ET_DYN)
8521da177e4SLinus Torvalds 		goto out;
853a62c5b1bSAlexey Dobriyan 	if (!elf_check_arch(elf_ex))
8541da177e4SLinus Torvalds 		goto out;
855a62c5b1bSAlexey Dobriyan 	if (elf_check_fdpic(elf_ex))
8564755200bSNicolas Pitre 		goto out;
85772c2d531SAl Viro 	if (!bprm->file->f_op->mmap)
8581da177e4SLinus Torvalds 		goto out;
8591da177e4SLinus Torvalds 
860a62c5b1bSAlexey Dobriyan 	elf_phdata = load_elf_phdrs(elf_ex, bprm->file);
8611da177e4SLinus Torvalds 	if (!elf_phdata)
8621da177e4SLinus Torvalds 		goto out;
8631da177e4SLinus Torvalds 
8641da177e4SLinus Torvalds 	elf_ppnt = elf_phdata;
865a62c5b1bSAlexey Dobriyan 	for (i = 0; i < elf_ex->e_phnum; i++, elf_ppnt++) {
866cc338010SAlexey Dobriyan 		char *elf_interpreter;
8675cf4a363SAlexey Dobriyan 
86800e19ceeSDave Martin 		if (elf_ppnt->p_type == PT_GNU_PROPERTY) {
86900e19ceeSDave Martin 			elf_property_phdata = elf_ppnt;
87000e19ceeSDave Martin 			continue;
87100e19ceeSDave Martin 		}
87200e19ceeSDave Martin 
873be0deb58SAlexey Dobriyan 		if (elf_ppnt->p_type != PT_INTERP)
874be0deb58SAlexey Dobriyan 			continue;
875be0deb58SAlexey Dobriyan 
876be0deb58SAlexey Dobriyan 		/*
877be0deb58SAlexey Dobriyan 		 * This is the program interpreter used for shared libraries -
878be0deb58SAlexey Dobriyan 		 * for now assume that this is an a.out format binary.
8791da177e4SLinus Torvalds 		 */
8801da177e4SLinus Torvalds 		retval = -ENOEXEC;
881be0deb58SAlexey Dobriyan 		if (elf_ppnt->p_filesz > PATH_MAX || elf_ppnt->p_filesz < 2)
882e7b9b550SAl Viro 			goto out_free_ph;
8831da177e4SLinus Torvalds 
8841da177e4SLinus Torvalds 		retval = -ENOMEM;
885be0deb58SAlexey Dobriyan 		elf_interpreter = kmalloc(elf_ppnt->p_filesz, GFP_KERNEL);
8861da177e4SLinus Torvalds 		if (!elf_interpreter)
887e7b9b550SAl Viro 			goto out_free_ph;
8881da177e4SLinus Torvalds 
889658c0335SAlexey Dobriyan 		retval = elf_read(bprm->file, elf_interpreter, elf_ppnt->p_filesz,
890658c0335SAlexey Dobriyan 				  elf_ppnt->p_offset);
891658c0335SAlexey Dobriyan 		if (retval < 0)
8921da177e4SLinus Torvalds 			goto out_free_interp;
8931da177e4SLinus Torvalds 		/* make sure path is NULL terminated */
8941da177e4SLinus Torvalds 		retval = -ENOEXEC;
8951da177e4SLinus Torvalds 		if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
8961da177e4SLinus Torvalds 			goto out_free_interp;
8971da177e4SLinus Torvalds 
8981da177e4SLinus Torvalds 		interpreter = open_exec(elf_interpreter);
899cc338010SAlexey Dobriyan 		kfree(elf_interpreter);
9001da177e4SLinus Torvalds 		retval = PTR_ERR(interpreter);
9011da177e4SLinus Torvalds 		if (IS_ERR(interpreter))
902cc338010SAlexey Dobriyan 			goto out_free_ph;
9031fb84496SAlexey Dobriyan 
9041fb84496SAlexey Dobriyan 		/*
905be0deb58SAlexey Dobriyan 		 * If the binary is not readable then enforce mm->dumpable = 0
906be0deb58SAlexey Dobriyan 		 * regardless of the interpreter's permissions.
9071fb84496SAlexey Dobriyan 		 */
9081b5d783cSAl Viro 		would_dump(bprm, interpreter);
9091fb84496SAlexey Dobriyan 
9100693ffebSAlexey Dobriyan 		interp_elf_ex = kmalloc(sizeof(*interp_elf_ex), GFP_KERNEL);
9110693ffebSAlexey Dobriyan 		if (!interp_elf_ex) {
9120693ffebSAlexey Dobriyan 			retval = -ENOMEM;
913594d2a14SLi Zetao 			goto out_free_file;
9140693ffebSAlexey Dobriyan 		}
9150693ffebSAlexey Dobriyan 
916b582ef5cSMaciej W. Rozycki 		/* Get the exec headers */
917c69bcc93SAlexey Dobriyan 		retval = elf_read(interpreter, interp_elf_ex,
918c69bcc93SAlexey Dobriyan 				  sizeof(*interp_elf_ex), 0);
919658c0335SAlexey Dobriyan 		if (retval < 0)
9201da177e4SLinus Torvalds 			goto out_free_dentry;
9211da177e4SLinus Torvalds 
9221da177e4SLinus Torvalds 		break;
923cc338010SAlexey Dobriyan 
924cc338010SAlexey Dobriyan out_free_interp:
925cc338010SAlexey Dobriyan 		kfree(elf_interpreter);
926cc338010SAlexey Dobriyan 		goto out_free_ph;
9271da177e4SLinus Torvalds 	}
9281da177e4SLinus Torvalds 
9291da177e4SLinus Torvalds 	elf_ppnt = elf_phdata;
930a62c5b1bSAlexey Dobriyan 	for (i = 0; i < elf_ex->e_phnum; i++, elf_ppnt++)
931774c105eSPaul Burton 		switch (elf_ppnt->p_type) {
932774c105eSPaul Burton 		case PT_GNU_STACK:
9331da177e4SLinus Torvalds 			if (elf_ppnt->p_flags & PF_X)
9341da177e4SLinus Torvalds 				executable_stack = EXSTACK_ENABLE_X;
9351da177e4SLinus Torvalds 			else
9361da177e4SLinus Torvalds 				executable_stack = EXSTACK_DISABLE_X;
9371da177e4SLinus Torvalds 			break;
938774c105eSPaul Burton 
939774c105eSPaul Burton 		case PT_LOPROC ... PT_HIPROC:
940a62c5b1bSAlexey Dobriyan 			retval = arch_elf_pt_proc(elf_ex, elf_ppnt,
941774c105eSPaul Burton 						  bprm->file, false,
942774c105eSPaul Burton 						  &arch_state);
943774c105eSPaul Burton 			if (retval)
944774c105eSPaul Burton 				goto out_free_dentry;
945774c105eSPaul Burton 			break;
9461da177e4SLinus Torvalds 		}
9471da177e4SLinus Torvalds 
9481da177e4SLinus Torvalds 	/* Some simple consistency checks for the interpreter */
949cc338010SAlexey Dobriyan 	if (interpreter) {
9501da177e4SLinus Torvalds 		retval = -ELIBBAD;
951d20894a2SAndi Kleen 		/* Not an ELF interpreter */
952c69bcc93SAlexey Dobriyan 		if (memcmp(interp_elf_ex->e_ident, ELFMAG, SELFMAG) != 0)
9531da177e4SLinus Torvalds 			goto out_free_dentry;
9541da177e4SLinus Torvalds 		/* Verify the interpreter has a valid arch */
955c69bcc93SAlexey Dobriyan 		if (!elf_check_arch(interp_elf_ex) ||
956c69bcc93SAlexey Dobriyan 		    elf_check_fdpic(interp_elf_ex))
9571da177e4SLinus Torvalds 			goto out_free_dentry;
958a9d9ef13SPaul Burton 
959a9d9ef13SPaul Burton 		/* Load the interpreter program headers */
960c69bcc93SAlexey Dobriyan 		interp_elf_phdata = load_elf_phdrs(interp_elf_ex,
961a9d9ef13SPaul Burton 						   interpreter);
962a9d9ef13SPaul Burton 		if (!interp_elf_phdata)
963a9d9ef13SPaul Burton 			goto out_free_dentry;
964774c105eSPaul Burton 
965774c105eSPaul Burton 		/* Pass PT_LOPROC..PT_HIPROC headers to arch code */
96600e19ceeSDave Martin 		elf_property_phdata = NULL;
967774c105eSPaul Burton 		elf_ppnt = interp_elf_phdata;
968c69bcc93SAlexey Dobriyan 		for (i = 0; i < interp_elf_ex->e_phnum; i++, elf_ppnt++)
969774c105eSPaul Burton 			switch (elf_ppnt->p_type) {
97000e19ceeSDave Martin 			case PT_GNU_PROPERTY:
97100e19ceeSDave Martin 				elf_property_phdata = elf_ppnt;
97200e19ceeSDave Martin 				break;
97300e19ceeSDave Martin 
974774c105eSPaul Burton 			case PT_LOPROC ... PT_HIPROC:
975c69bcc93SAlexey Dobriyan 				retval = arch_elf_pt_proc(interp_elf_ex,
976774c105eSPaul Burton 							  elf_ppnt, interpreter,
977774c105eSPaul Burton 							  true, &arch_state);
978774c105eSPaul Burton 				if (retval)
979774c105eSPaul Burton 					goto out_free_dentry;
980774c105eSPaul Burton 				break;
9811da177e4SLinus Torvalds 			}
982774c105eSPaul Burton 	}
983774c105eSPaul Burton 
98400e19ceeSDave Martin 	retval = parse_elf_properties(interpreter ?: bprm->file,
98500e19ceeSDave Martin 				      elf_property_phdata, &arch_state);
98600e19ceeSDave Martin 	if (retval)
98700e19ceeSDave Martin 		goto out_free_dentry;
98800e19ceeSDave Martin 
989774c105eSPaul Burton 	/*
990774c105eSPaul Burton 	 * Allow arch code to reject the ELF at this point, whilst it's
991774c105eSPaul Burton 	 * still possible to return an error to the code that invoked
992774c105eSPaul Burton 	 * the exec syscall.
993774c105eSPaul Burton 	 */
994a62c5b1bSAlexey Dobriyan 	retval = arch_check_elf(elf_ex,
995c69bcc93SAlexey Dobriyan 				!!interpreter, interp_elf_ex,
996eb4bc076SMaciej W. Rozycki 				&arch_state);
997774c105eSPaul Burton 	if (retval)
998774c105eSPaul Burton 		goto out_free_dentry;
9991da177e4SLinus Torvalds 
10001da177e4SLinus Torvalds 	/* Flush all traces of the currently running executable */
10012388777aSEric W. Biederman 	retval = begin_new_exec(bprm);
10021da177e4SLinus Torvalds 	if (retval)
10031da177e4SLinus Torvalds 		goto out_free_dentry;
10041da177e4SLinus Torvalds 
10051da177e4SLinus Torvalds 	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
10061da177e4SLinus Torvalds 	   may depend on the personality.  */
1007a62c5b1bSAlexey Dobriyan 	SET_PERSONALITY2(*elf_ex, &arch_state);
1008a62c5b1bSAlexey Dobriyan 	if (elf_read_implies_exec(*elf_ex, executable_stack))
10091da177e4SLinus Torvalds 		current->personality |= READ_IMPLIES_EXEC;
10101da177e4SLinus Torvalds 
1011*53f17409SAlexey Dobriyan 	const int snapshot_randomize_va_space = READ_ONCE(randomize_va_space);
1012*53f17409SAlexey Dobriyan 	if (!(current->personality & ADDR_NO_RANDOMIZE) && snapshot_randomize_va_space)
10131da177e4SLinus Torvalds 		current->flags |= PF_RANDOMIZE;
1014221af7f8SLinus Torvalds 
1015221af7f8SLinus Torvalds 	setup_new_exec(bprm);
10161da177e4SLinus Torvalds 
10171da177e4SLinus Torvalds 	/* Do this so that we can load the interpreter, if need be.  We will
10181da177e4SLinus Torvalds 	   change some of these later */
10191da177e4SLinus Torvalds 	retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
10201da177e4SLinus Torvalds 				 executable_stack);
102119d860a1SAl Viro 	if (retval < 0)
10221da177e4SLinus Torvalds 		goto out_free_dentry;
10231da177e4SLinus Torvalds 
102485264316SAlexey Dobriyan 	elf_bss = 0;
102585264316SAlexey Dobriyan 	elf_brk = 0;
102685264316SAlexey Dobriyan 
102785264316SAlexey Dobriyan 	start_code = ~0UL;
102885264316SAlexey Dobriyan 	end_code = 0;
102985264316SAlexey Dobriyan 	start_data = 0;
103085264316SAlexey Dobriyan 	end_data = 0;
103185264316SAlexey Dobriyan 
1032af901ca1SAndré Goddard Rosa 	/* Now we do a little grungy work by mmapping the ELF image into
1033cc503c1bSJiri Kosina 	   the correct location in memory. */
1034f4e5cc2cSJesper Juhl 	for(i = 0, elf_ppnt = elf_phdata;
1035a62c5b1bSAlexey Dobriyan 	    i < elf_ex->e_phnum; i++, elf_ppnt++) {
1036b212921bSLinus Torvalds 		int elf_prot, elf_flags;
10371da177e4SLinus Torvalds 		unsigned long k, vaddr;
1038a87938b2SMichael Davidson 		unsigned long total_size = 0;
1039ce81bb25SChris Kennelly 		unsigned long alignment;
10401da177e4SLinus Torvalds 
10411da177e4SLinus Torvalds 		if (elf_ppnt->p_type != PT_LOAD)
10421da177e4SLinus Torvalds 			continue;
10431da177e4SLinus Torvalds 
10441da177e4SLinus Torvalds 		if (unlikely (elf_brk > elf_bss)) {
10451da177e4SLinus Torvalds 			unsigned long nbyte;
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds 			/* There was a PT_LOAD segment with p_memsz > p_filesz
10481da177e4SLinus Torvalds 			   before this one. Map anonymous pages, if needed,
10491da177e4SLinus Torvalds 			   and clear the area.  */
10501da177e4SLinus Torvalds 			retval = set_brk(elf_bss + load_bias,
105116e72e9bSDenys Vlasenko 					 elf_brk + load_bias,
105216e72e9bSDenys Vlasenko 					 bss_prot);
105319d860a1SAl Viro 			if (retval)
10541da177e4SLinus Torvalds 				goto out_free_dentry;
10551da177e4SLinus Torvalds 			nbyte = ELF_PAGEOFFSET(elf_bss);
10561da177e4SLinus Torvalds 			if (nbyte) {
10571da177e4SLinus Torvalds 				nbyte = ELF_MIN_ALIGN - nbyte;
10581da177e4SLinus Torvalds 				if (nbyte > elf_brk - elf_bss)
10591da177e4SLinus Torvalds 					nbyte = elf_brk - elf_bss;
10601da177e4SLinus Torvalds 				if (clear_user((void __user *)elf_bss +
10611da177e4SLinus Torvalds 							load_bias, nbyte)) {
10621da177e4SLinus Torvalds 					/*
10631da177e4SLinus Torvalds 					 * This bss-zeroing can fail if the ELF
10641da177e4SLinus Torvalds 					 * file specifies odd protections. So
10651da177e4SLinus Torvalds 					 * we don't check the return value
10661da177e4SLinus Torvalds 					 */
10671da177e4SLinus Torvalds 				}
10681da177e4SLinus Torvalds 			}
10691da177e4SLinus Torvalds 		}
10701da177e4SLinus Torvalds 
1071fe0f6766SDave Martin 		elf_prot = make_prot(elf_ppnt->p_flags, &arch_state,
1072fe0f6766SDave Martin 				     !!interpreter, false);
10731da177e4SLinus Torvalds 
10744589ff7cSDavid Hildenbrand 		elf_flags = MAP_PRIVATE;
10751da177e4SLinus Torvalds 
10761da177e4SLinus Torvalds 		vaddr = elf_ppnt->p_vaddr;
1077eab09532SKees Cook 		/*
10782b4bfbe0SAkira Kawata 		 * The first time through the loop, first_pt_load is true:
10795f501d55SKees Cook 		 * layout will be calculated. Once set, use MAP_FIXED since
10805f501d55SKees Cook 		 * we know we've already safely mapped the entire region with
10815f501d55SKees Cook 		 * MAP_FIXED_NOREPLACE in the once-per-binary logic following.
1082eab09532SKees Cook 		 */
10832b4bfbe0SAkira Kawata 		if (!first_pt_load) {
1084b212921bSLinus Torvalds 			elf_flags |= MAP_FIXED;
10855f501d55SKees Cook 		} else if (elf_ex->e_type == ET_EXEC) {
10865f501d55SKees Cook 			/*
10875f501d55SKees Cook 			 * This logic is run once for the first LOAD Program
10885f501d55SKees Cook 			 * Header for ET_EXEC binaries. No special handling
10895f501d55SKees Cook 			 * is needed.
10905f501d55SKees Cook 			 */
10915f501d55SKees Cook 			elf_flags |= MAP_FIXED_NOREPLACE;
1092a62c5b1bSAlexey Dobriyan 		} else if (elf_ex->e_type == ET_DYN) {
1093eab09532SKees Cook 			/*
1094eab09532SKees Cook 			 * This logic is run once for the first LOAD Program
1095eab09532SKees Cook 			 * Header for ET_DYN binaries to calculate the
1096eab09532SKees Cook 			 * randomization (load_bias) for all the LOAD
10975f501d55SKees Cook 			 * Program Headers.
1098eab09532SKees Cook 			 *
1099eab09532SKees Cook 			 * There are effectively two types of ET_DYN
1100eab09532SKees Cook 			 * binaries: programs (i.e. PIE: ET_DYN with INTERP)
1101eab09532SKees Cook 			 * and loaders (ET_DYN without INTERP, since they
1102eab09532SKees Cook 			 * _are_ the ELF interpreter). The loaders must
1103eab09532SKees Cook 			 * be loaded away from programs since the program
1104eab09532SKees Cook 			 * may otherwise collide with the loader (especially
1105eab09532SKees Cook 			 * for ET_EXEC which does not have a randomized
1106eab09532SKees Cook 			 * position). For example to handle invocations of
1107eab09532SKees Cook 			 * "./ld.so someprog" to test out a new version of
1108eab09532SKees Cook 			 * the loader, the subsequent program that the
1109eab09532SKees Cook 			 * loader loads must avoid the loader itself, so
1110eab09532SKees Cook 			 * they cannot share the same load range. Sufficient
1111eab09532SKees Cook 			 * room for the brk must be allocated with the
1112eab09532SKees Cook 			 * loader as well, since brk must be available with
1113eab09532SKees Cook 			 * the loader.
1114eab09532SKees Cook 			 *
1115eab09532SKees Cook 			 * Therefore, programs are loaded offset from
1116eab09532SKees Cook 			 * ELF_ET_DYN_BASE and loaders are loaded into the
1117eab09532SKees Cook 			 * independently randomized mmap region (0 load_bias
11185f501d55SKees Cook 			 * without MAP_FIXED nor MAP_FIXED_NOREPLACE).
1119eab09532SKees Cook 			 */
1120aeb79237SAndrew Morton 			if (interpreter) {
1121eab09532SKees Cook 				load_bias = ELF_ET_DYN_BASE;
1122a3defbe5SJiri Kosina 				if (current->flags & PF_RANDOMIZE)
1123d1fd836dSKees Cook 					load_bias += arch_mmap_rnd();
1124aeb79237SAndrew Morton 				alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum);
1125ce81bb25SChris Kennelly 				if (alignment)
1126ce81bb25SChris Kennelly 					load_bias &= ~(alignment - 1);
11275f501d55SKees Cook 				elf_flags |= MAP_FIXED_NOREPLACE;
1128eab09532SKees Cook 			} else
1129eab09532SKees Cook 				load_bias = 0;
1130eab09532SKees Cook 
1131eab09532SKees Cook 			/*
1132eab09532SKees Cook 			 * Since load_bias is used for all subsequent loading
1133eab09532SKees Cook 			 * calculations, we must lower it by the first vaddr
1134eab09532SKees Cook 			 * so that the remaining calculations based on the
1135eab09532SKees Cook 			 * ELF vaddrs will be correctly offset. The result
1136eab09532SKees Cook 			 * is then page aligned.
1137eab09532SKees Cook 			 */
1138eab09532SKees Cook 			load_bias = ELF_PAGESTART(load_bias - vaddr);
1139eab09532SKees Cook 
11405f501d55SKees Cook 			/*
1141439a8468SKees Cook 			 * Calculate the entire size of the ELF mapping
1142439a8468SKees Cook 			 * (total_size), used for the initial mapping,
1143439a8468SKees Cook 			 * due to load_addr_set which is set to true later
1144439a8468SKees Cook 			 * once the initial mapping is performed.
1145439a8468SKees Cook 			 *
1146439a8468SKees Cook 			 * Note that this is only sensible when the LOAD
1147439a8468SKees Cook 			 * segments are contiguous (or overlapping). If
1148439a8468SKees Cook 			 * used for LOADs that are far apart, this would
1149439a8468SKees Cook 			 * cause the holes between LOADs to be mapped,
1150439a8468SKees Cook 			 * running the risk of having the mapping fail,
1151439a8468SKees Cook 			 * as it would be larger than the ELF file itself.
1152439a8468SKees Cook 			 *
1153439a8468SKees Cook 			 * As a result, only ET_DYN does this, since
1154439a8468SKees Cook 			 * some ET_EXEC (e.g. ia64) may have large virtual
1155439a8468SKees Cook 			 * memory holes between LOADs.
1156439a8468SKees Cook 			 *
11575f501d55SKees Cook 			 */
1158a87938b2SMichael Davidson 			total_size = total_mapping_size(elf_phdata,
1159a62c5b1bSAlexey Dobriyan 							elf_ex->e_phnum);
1160a87938b2SMichael Davidson 			if (!total_size) {
11612b1d3ae9SAndrew Morton 				retval = -EINVAL;
1162a87938b2SMichael Davidson 				goto out_free_dentry;
1163a87938b2SMichael Davidson 			}
11641da177e4SLinus Torvalds 		}
11651da177e4SLinus Torvalds 
1166f4e5cc2cSJesper Juhl 		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
1167a87938b2SMichael Davidson 				elf_prot, elf_flags, total_size);
11681da177e4SLinus Torvalds 		if (BAD_ADDR(error)) {
1169dc64cc12SBo Liu 			retval = IS_ERR_VALUE(error) ?
1170b140f251SAlexey Kuznetsov 				PTR_ERR((void*)error) : -EINVAL;
11711da177e4SLinus Torvalds 			goto out_free_dentry;
11721da177e4SLinus Torvalds 		}
11731da177e4SLinus Torvalds 
11742b4bfbe0SAkira Kawata 		if (first_pt_load) {
11752b4bfbe0SAkira Kawata 			first_pt_load = 0;
1176a62c5b1bSAlexey Dobriyan 			if (elf_ex->e_type == ET_DYN) {
11771da177e4SLinus Torvalds 				load_bias += error -
11781da177e4SLinus Torvalds 				             ELF_PAGESTART(load_bias + vaddr);
11791da177e4SLinus Torvalds 				reloc_func_desc = load_bias;
11801da177e4SLinus Torvalds 			}
11811da177e4SLinus Torvalds 		}
11820da1d500SAkira Kawata 
11830da1d500SAkira Kawata 		/*
11840da1d500SAkira Kawata 		 * Figure out which segment in the file contains the Program
11850da1d500SAkira Kawata 		 * Header table, and map to the associated memory address.
11860da1d500SAkira Kawata 		 */
11870da1d500SAkira Kawata 		if (elf_ppnt->p_offset <= elf_ex->e_phoff &&
11880da1d500SAkira Kawata 		    elf_ex->e_phoff < elf_ppnt->p_offset + elf_ppnt->p_filesz) {
11890da1d500SAkira Kawata 			phdr_addr = elf_ex->e_phoff - elf_ppnt->p_offset +
11900da1d500SAkira Kawata 				    elf_ppnt->p_vaddr;
11910da1d500SAkira Kawata 		}
11920da1d500SAkira Kawata 
11931da177e4SLinus Torvalds 		k = elf_ppnt->p_vaddr;
1194f67ef446SAlexey Dobriyan 		if ((elf_ppnt->p_flags & PF_X) && k < start_code)
1195f4e5cc2cSJesper Juhl 			start_code = k;
1196f4e5cc2cSJesper Juhl 		if (start_data < k)
1197f4e5cc2cSJesper Juhl 			start_data = k;
11981da177e4SLinus Torvalds 
11991da177e4SLinus Torvalds 		/*
12001da177e4SLinus Torvalds 		 * Check to see if the section's size will overflow the
12011da177e4SLinus Torvalds 		 * allowed task size. Note that p_filesz must always be
12021da177e4SLinus Torvalds 		 * <= p_memsz so it is only necessary to check p_memsz.
12031da177e4SLinus Torvalds 		 */
1204ce51059bSChuck Ebbert 		if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
12051da177e4SLinus Torvalds 		    elf_ppnt->p_memsz > TASK_SIZE ||
12061da177e4SLinus Torvalds 		    TASK_SIZE - elf_ppnt->p_memsz < k) {
12071da177e4SLinus Torvalds 			/* set_brk can never work. Avoid overflows. */
1208b140f251SAlexey Kuznetsov 			retval = -EINVAL;
12091da177e4SLinus Torvalds 			goto out_free_dentry;
12101da177e4SLinus Torvalds 		}
12111da177e4SLinus Torvalds 
12121da177e4SLinus Torvalds 		k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
12131da177e4SLinus Torvalds 
12141da177e4SLinus Torvalds 		if (k > elf_bss)
12151da177e4SLinus Torvalds 			elf_bss = k;
12161da177e4SLinus Torvalds 		if ((elf_ppnt->p_flags & PF_X) && end_code < k)
12171da177e4SLinus Torvalds 			end_code = k;
12181da177e4SLinus Torvalds 		if (end_data < k)
12191da177e4SLinus Torvalds 			end_data = k;
12201da177e4SLinus Torvalds 		k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
122116e72e9bSDenys Vlasenko 		if (k > elf_brk) {
122216e72e9bSDenys Vlasenko 			bss_prot = elf_prot;
12231da177e4SLinus Torvalds 			elf_brk = k;
12241da177e4SLinus Torvalds 		}
122516e72e9bSDenys Vlasenko 	}
12261da177e4SLinus Torvalds 
1227a62c5b1bSAlexey Dobriyan 	e_entry = elf_ex->e_entry + load_bias;
12280da1d500SAkira Kawata 	phdr_addr += load_bias;
12291da177e4SLinus Torvalds 	elf_bss += load_bias;
12301da177e4SLinus Torvalds 	elf_brk += load_bias;
12311da177e4SLinus Torvalds 	start_code += load_bias;
12321da177e4SLinus Torvalds 	end_code += load_bias;
12331da177e4SLinus Torvalds 	start_data += load_bias;
12341da177e4SLinus Torvalds 	end_data += load_bias;
12351da177e4SLinus Torvalds 
12361da177e4SLinus Torvalds 	/* Calling set_brk effectively mmaps the pages that we need
12371da177e4SLinus Torvalds 	 * for the bss and break sections.  We must do this before
12381da177e4SLinus Torvalds 	 * mapping in the interpreter, to make sure it doesn't wind
12391da177e4SLinus Torvalds 	 * up getting placed where the bss needs to go.
12401da177e4SLinus Torvalds 	 */
124116e72e9bSDenys Vlasenko 	retval = set_brk(elf_bss, elf_brk, bss_prot);
124219d860a1SAl Viro 	if (retval)
12431da177e4SLinus Torvalds 		goto out_free_dentry;
12446de50517Sakpm@osdl.org 	if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
12451da177e4SLinus Torvalds 		retval = -EFAULT; /* Nobody gets to see this, but.. */
12461da177e4SLinus Torvalds 		goto out_free_dentry;
12471da177e4SLinus Torvalds 	}
12481da177e4SLinus Torvalds 
1249cc338010SAlexey Dobriyan 	if (interpreter) {
1250c69bcc93SAlexey Dobriyan 		elf_entry = load_elf_interp(interp_elf_ex,
12511da177e4SLinus Torvalds 					    interpreter,
1252fe0f6766SDave Martin 					    load_bias, interp_elf_phdata,
1253fe0f6766SDave Martin 					    &arch_state);
1254dc64cc12SBo Liu 		if (!IS_ERR_VALUE(elf_entry)) {
1255cc503c1bSJiri Kosina 			/*
1256cc503c1bSJiri Kosina 			 * load_elf_interp() returns relocation
1257cc503c1bSJiri Kosina 			 * adjustment
1258cc503c1bSJiri Kosina 			 */
1259cc503c1bSJiri Kosina 			interp_load_addr = elf_entry;
1260c69bcc93SAlexey Dobriyan 			elf_entry += interp_elf_ex->e_entry;
1261cc503c1bSJiri Kosina 		}
12621da177e4SLinus Torvalds 		if (BAD_ADDR(elf_entry)) {
1263dc64cc12SBo Liu 			retval = IS_ERR_VALUE(elf_entry) ?
1264ce51059bSChuck Ebbert 					(int)elf_entry : -EINVAL;
12651da177e4SLinus Torvalds 			goto out_free_dentry;
12661da177e4SLinus Torvalds 		}
12671da177e4SLinus Torvalds 		reloc_func_desc = interp_load_addr;
12681da177e4SLinus Torvalds 
12691da177e4SLinus Torvalds 		allow_write_access(interpreter);
12701da177e4SLinus Torvalds 		fput(interpreter);
12710693ffebSAlexey Dobriyan 
12720693ffebSAlexey Dobriyan 		kfree(interp_elf_ex);
1273aa0d1564SAlexey Dobriyan 		kfree(interp_elf_phdata);
12741da177e4SLinus Torvalds 	} else {
1275a62c5b1bSAlexey Dobriyan 		elf_entry = e_entry;
12765342fba5SSuresh Siddha 		if (BAD_ADDR(elf_entry)) {
1277ce51059bSChuck Ebbert 			retval = -EINVAL;
12785342fba5SSuresh Siddha 			goto out_free_dentry;
12795342fba5SSuresh Siddha 		}
12801da177e4SLinus Torvalds 	}
12811da177e4SLinus Torvalds 
12821da177e4SLinus Torvalds 	kfree(elf_phdata);
12831da177e4SLinus Torvalds 
12841da177e4SLinus Torvalds 	set_binfmt(&elf_format);
12851da177e4SLinus Torvalds 
1286547ee84cSBenjamin Herrenschmidt #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
12879a29a671SGabriel Krisman Bertazi 	retval = ARCH_SETUP_ADDITIONAL_PAGES(bprm, elf_ex, !!interpreter);
128819d860a1SAl Viro 	if (retval < 0)
128918c8baffSRoland McGrath 		goto out;
1290547ee84cSBenjamin Herrenschmidt #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
1291547ee84cSBenjamin Herrenschmidt 
12920da1d500SAkira Kawata 	retval = create_elf_tables(bprm, elf_ex, interp_load_addr,
12930da1d500SAkira Kawata 				   e_entry, phdr_addr);
129419d860a1SAl Viro 	if (retval < 0)
1295b6a2fea3SOllie Wild 		goto out;
129603c6d723SAlexey Dobriyan 
129703c6d723SAlexey Dobriyan 	mm = current->mm;
129803c6d723SAlexey Dobriyan 	mm->end_code = end_code;
129903c6d723SAlexey Dobriyan 	mm->start_code = start_code;
130003c6d723SAlexey Dobriyan 	mm->start_data = start_data;
130103c6d723SAlexey Dobriyan 	mm->end_data = end_data;
130203c6d723SAlexey Dobriyan 	mm->start_stack = bprm->p;
13031da177e4SLinus Torvalds 
1304*53f17409SAlexey Dobriyan 	if ((current->flags & PF_RANDOMIZE) && (snapshot_randomize_va_space > 1)) {
1305bbdc6076SKees Cook 		/*
1306bbdc6076SKees Cook 		 * For architectures with ELF randomization, when executing
1307bbdc6076SKees Cook 		 * a loader directly (i.e. no interpreter listed in ELF
1308bbdc6076SKees Cook 		 * headers), move the brk area out of the mmap region
1309bbdc6076SKees Cook 		 * (since it grows up, and may collide early with the stack
1310bbdc6076SKees Cook 		 * growing down), and into the unused ELF_ET_DYN_BASE region.
1311bbdc6076SKees Cook 		 */
13127be3cb01SKees Cook 		if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) &&
131303c6d723SAlexey Dobriyan 		    elf_ex->e_type == ET_DYN && !interpreter) {
131403c6d723SAlexey Dobriyan 			mm->brk = mm->start_brk = ELF_ET_DYN_BASE;
131503c6d723SAlexey Dobriyan 		}
1316bbdc6076SKees Cook 
131703c6d723SAlexey Dobriyan 		mm->brk = mm->start_brk = arch_randomize_brk(mm);
1318204db6edSKees Cook #ifdef compat_brk_randomized
13194471a675SJiri Kosina 		current->brk_randomized = 1;
13204471a675SJiri Kosina #endif
13214471a675SJiri Kosina 	}
1322c1d171a0SJiri Kosina 
13231da177e4SLinus Torvalds 	if (current->personality & MMAP_PAGE_ZERO) {
13241da177e4SLinus Torvalds 		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
13251da177e4SLinus Torvalds 		   and some applications "depend" upon this behavior.
13261da177e4SLinus Torvalds 		   Since we do not have the power to recompile these, we
13271da177e4SLinus Torvalds 		   emulate the SVr4 behavior. Sigh. */
13286be5ceb0SLinus Torvalds 		error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
13291da177e4SLinus Torvalds 				MAP_FIXED | MAP_PRIVATE, 0);
13301da177e4SLinus Torvalds 	}
13311da177e4SLinus Torvalds 
1332249b08e4SAlexey Dobriyan 	regs = current_pt_regs();
13331da177e4SLinus Torvalds #ifdef ELF_PLAT_INIT
13341da177e4SLinus Torvalds 	/*
13351da177e4SLinus Torvalds 	 * The ABI may specify that certain registers be set up in special
13361da177e4SLinus Torvalds 	 * ways (on i386 %edx is the address of a DT_FINI function, for
13371da177e4SLinus Torvalds 	 * example.  In addition, it may also specify (eg, PowerPC64 ELF)
13381da177e4SLinus Torvalds 	 * that the e_entry field is the address of the function descriptor
13391da177e4SLinus Torvalds 	 * for the startup routine, rather than the address of the startup
13401da177e4SLinus Torvalds 	 * routine itself.  This macro performs whatever initialization to
13411da177e4SLinus Torvalds 	 * the regs structure is required as well as any relocations to the
13421da177e4SLinus Torvalds 	 * function descriptor entries when executing dynamically links apps.
13431da177e4SLinus Torvalds 	 */
13441da177e4SLinus Torvalds 	ELF_PLAT_INIT(regs, reloc_func_desc);
13451da177e4SLinus Torvalds #endif
13461da177e4SLinus Torvalds 
1347b8383831SKees Cook 	finalize_exec(bprm);
1348bc3d7bf6SGabriel Krisman Bertazi 	START_THREAD(elf_ex, regs, elf_entry, bprm->p);
13491da177e4SLinus Torvalds 	retval = 0;
13501da177e4SLinus Torvalds out:
13511da177e4SLinus Torvalds 	return retval;
13521da177e4SLinus Torvalds 
13531da177e4SLinus Torvalds 	/* error cleanup */
13541da177e4SLinus Torvalds out_free_dentry:
13550693ffebSAlexey Dobriyan 	kfree(interp_elf_ex);
1356a9d9ef13SPaul Burton 	kfree(interp_elf_phdata);
1357594d2a14SLi Zetao out_free_file:
13581da177e4SLinus Torvalds 	allow_write_access(interpreter);
13591da177e4SLinus Torvalds 	if (interpreter)
13601da177e4SLinus Torvalds 		fput(interpreter);
13611da177e4SLinus Torvalds out_free_ph:
13621da177e4SLinus Torvalds 	kfree(elf_phdata);
13631da177e4SLinus Torvalds 	goto out;
13641da177e4SLinus Torvalds }
13651da177e4SLinus Torvalds 
136669369a70SJosh Triplett #ifdef CONFIG_USELIB
13671da177e4SLinus Torvalds /* This is really simpleminded and specialized - we are loading an
13681da177e4SLinus Torvalds    a.out library that is given an ELF header. */
load_elf_library(struct file * file)13691da177e4SLinus Torvalds static int load_elf_library(struct file *file)
13701da177e4SLinus Torvalds {
13711da177e4SLinus Torvalds 	struct elf_phdr *elf_phdata;
13721da177e4SLinus Torvalds 	struct elf_phdr *eppnt;
13731da177e4SLinus Torvalds 	unsigned long elf_bss, bss, len;
13741da177e4SLinus Torvalds 	int retval, error, i, j;
13751da177e4SLinus Torvalds 	struct elfhdr elf_ex;
13761da177e4SLinus Torvalds 
13771da177e4SLinus Torvalds 	error = -ENOEXEC;
1378658c0335SAlexey Dobriyan 	retval = elf_read(file, &elf_ex, sizeof(elf_ex), 0);
1379658c0335SAlexey Dobriyan 	if (retval < 0)
13801da177e4SLinus Torvalds 		goto out;
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds 	if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
13831da177e4SLinus Torvalds 		goto out;
13841da177e4SLinus Torvalds 
13851da177e4SLinus Torvalds 	/* First of all, some simple consistency checks */
13861da177e4SLinus Torvalds 	if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
138772c2d531SAl Viro 	    !elf_check_arch(&elf_ex) || !file->f_op->mmap)
13881da177e4SLinus Torvalds 		goto out;
13894755200bSNicolas Pitre 	if (elf_check_fdpic(&elf_ex))
13904755200bSNicolas Pitre 		goto out;
13911da177e4SLinus Torvalds 
13921da177e4SLinus Torvalds 	/* Now read in all of the header information */
13931da177e4SLinus Torvalds 
13941da177e4SLinus Torvalds 	j = sizeof(struct elf_phdr) * elf_ex.e_phnum;
13951da177e4SLinus Torvalds 	/* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */
13961da177e4SLinus Torvalds 
13971da177e4SLinus Torvalds 	error = -ENOMEM;
13981da177e4SLinus Torvalds 	elf_phdata = kmalloc(j, GFP_KERNEL);
13991da177e4SLinus Torvalds 	if (!elf_phdata)
14001da177e4SLinus Torvalds 		goto out;
14011da177e4SLinus Torvalds 
14021da177e4SLinus Torvalds 	eppnt = elf_phdata;
14031da177e4SLinus Torvalds 	error = -ENOEXEC;
1404658c0335SAlexey Dobriyan 	retval = elf_read(file, eppnt, j, elf_ex.e_phoff);
1405658c0335SAlexey Dobriyan 	if (retval < 0)
14061da177e4SLinus Torvalds 		goto out_free_ph;
14071da177e4SLinus Torvalds 
14081da177e4SLinus Torvalds 	for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
14091da177e4SLinus Torvalds 		if ((eppnt + i)->p_type == PT_LOAD)
14101da177e4SLinus Torvalds 			j++;
14111da177e4SLinus Torvalds 	if (j != 1)
14121da177e4SLinus Torvalds 		goto out_free_ph;
14131da177e4SLinus Torvalds 
14141da177e4SLinus Torvalds 	while (eppnt->p_type != PT_LOAD)
14151da177e4SLinus Torvalds 		eppnt++;
14161da177e4SLinus Torvalds 
14171da177e4SLinus Torvalds 	/* Now use mmap to map the library into memory. */
14186be5ceb0SLinus Torvalds 	error = vm_mmap(file,
14191da177e4SLinus Torvalds 			ELF_PAGESTART(eppnt->p_vaddr),
14201da177e4SLinus Torvalds 			(eppnt->p_filesz +
14211da177e4SLinus Torvalds 			 ELF_PAGEOFFSET(eppnt->p_vaddr)),
14221da177e4SLinus Torvalds 			PROT_READ | PROT_WRITE | PROT_EXEC,
142342be8b42SDavid Hildenbrand 			MAP_FIXED_NOREPLACE | MAP_PRIVATE,
14241da177e4SLinus Torvalds 			(eppnt->p_offset -
14251da177e4SLinus Torvalds 			 ELF_PAGEOFFSET(eppnt->p_vaddr)));
14261da177e4SLinus Torvalds 	if (error != ELF_PAGESTART(eppnt->p_vaddr))
14271da177e4SLinus Torvalds 		goto out_free_ph;
14281da177e4SLinus Torvalds 
14291da177e4SLinus Torvalds 	elf_bss = eppnt->p_vaddr + eppnt->p_filesz;
14301da177e4SLinus Torvalds 	if (padzero(elf_bss)) {
14311da177e4SLinus Torvalds 		error = -EFAULT;
14321da177e4SLinus Torvalds 		goto out_free_ph;
14331da177e4SLinus Torvalds 	}
14341da177e4SLinus Torvalds 
143524962af7SOscar Salvador 	len = ELF_PAGEALIGN(eppnt->p_filesz + eppnt->p_vaddr);
143624962af7SOscar Salvador 	bss = ELF_PAGEALIGN(eppnt->p_memsz + eppnt->p_vaddr);
1437ecc2bc8aSMichal Hocko 	if (bss > len) {
1438ecc2bc8aSMichal Hocko 		error = vm_brk(len, bss - len);
14395d22fc25SLinus Torvalds 		if (error)
1440ecc2bc8aSMichal Hocko 			goto out_free_ph;
1441ecc2bc8aSMichal Hocko 	}
14421da177e4SLinus Torvalds 	error = 0;
14431da177e4SLinus Torvalds 
14441da177e4SLinus Torvalds out_free_ph:
14451da177e4SLinus Torvalds 	kfree(elf_phdata);
14461da177e4SLinus Torvalds out:
14471da177e4SLinus Torvalds 	return error;
14481da177e4SLinus Torvalds }
144969369a70SJosh Triplett #endif /* #ifdef CONFIG_USELIB */
14501da177e4SLinus Torvalds 
1451698ba7b5SChristoph Hellwig #ifdef CONFIG_ELF_CORE
14521da177e4SLinus Torvalds /*
14531da177e4SLinus Torvalds  * ELF core dumper
14541da177e4SLinus Torvalds  *
14551da177e4SLinus Torvalds  * Modelled on fs/exec.c:aout_core_dump()
14561da177e4SLinus Torvalds  * Jeremy Fitzhardinge <jeremy@sw.oz.au>
14571da177e4SLinus Torvalds  */
14581da177e4SLinus Torvalds 
14591da177e4SLinus Torvalds /* An ELF note in memory */
14601da177e4SLinus Torvalds struct memelfnote
14611da177e4SLinus Torvalds {
14621da177e4SLinus Torvalds 	const char *name;
14631da177e4SLinus Torvalds 	int type;
14641da177e4SLinus Torvalds 	unsigned int datasz;
14651da177e4SLinus Torvalds 	void *data;
14661da177e4SLinus Torvalds };
14671da177e4SLinus Torvalds 
notesize(struct memelfnote * en)14681da177e4SLinus Torvalds static int notesize(struct memelfnote *en)
14691da177e4SLinus Torvalds {
14701da177e4SLinus Torvalds 	int sz;
14711da177e4SLinus Torvalds 
14721da177e4SLinus Torvalds 	sz = sizeof(struct elf_note);
14731da177e4SLinus Torvalds 	sz += roundup(strlen(en->name) + 1, 4);
14741da177e4SLinus Torvalds 	sz += roundup(en->datasz, 4);
14751da177e4SLinus Torvalds 
14761da177e4SLinus Torvalds 	return sz;
14771da177e4SLinus Torvalds }
14781da177e4SLinus Torvalds 
writenote(struct memelfnote * men,struct coredump_params * cprm)1479ecc8c772SAl Viro static int writenote(struct memelfnote *men, struct coredump_params *cprm)
14801da177e4SLinus Torvalds {
14811da177e4SLinus Torvalds 	struct elf_note en;
14821da177e4SLinus Torvalds 	en.n_namesz = strlen(men->name) + 1;
14831da177e4SLinus Torvalds 	en.n_descsz = men->datasz;
14841da177e4SLinus Torvalds 	en.n_type = men->type;
14851da177e4SLinus Torvalds 
1486ecc8c772SAl Viro 	return dump_emit(cprm, &en, sizeof(en)) &&
148722a8cb82SAl Viro 	    dump_emit(cprm, men->name, en.n_namesz) && dump_align(cprm, 4) &&
148822a8cb82SAl Viro 	    dump_emit(cprm, men->data, men->datasz) && dump_align(cprm, 4);
14891da177e4SLinus Torvalds }
14901da177e4SLinus Torvalds 
fill_elf_header(struct elfhdr * elf,int segs,u16 machine,u32 flags)14913aba481fSRoland McGrath static void fill_elf_header(struct elfhdr *elf, int segs,
1492d3330cf0SZhang Yanfei 			    u16 machine, u32 flags)
14931da177e4SLinus Torvalds {
14946970c8efSCyrill Gorcunov 	memset(elf, 0, sizeof(*elf));
14956970c8efSCyrill Gorcunov 
14961da177e4SLinus Torvalds 	memcpy(elf->e_ident, ELFMAG, SELFMAG);
14971da177e4SLinus Torvalds 	elf->e_ident[EI_CLASS] = ELF_CLASS;
14981da177e4SLinus Torvalds 	elf->e_ident[EI_DATA] = ELF_DATA;
14991da177e4SLinus Torvalds 	elf->e_ident[EI_VERSION] = EV_CURRENT;
15001da177e4SLinus Torvalds 	elf->e_ident[EI_OSABI] = ELF_OSABI;
15011da177e4SLinus Torvalds 
15021da177e4SLinus Torvalds 	elf->e_type = ET_CORE;
15033aba481fSRoland McGrath 	elf->e_machine = machine;
15041da177e4SLinus Torvalds 	elf->e_version = EV_CURRENT;
15051da177e4SLinus Torvalds 	elf->e_phoff = sizeof(struct elfhdr);
15063aba481fSRoland McGrath 	elf->e_flags = flags;
15071da177e4SLinus Torvalds 	elf->e_ehsize = sizeof(struct elfhdr);
15081da177e4SLinus Torvalds 	elf->e_phentsize = sizeof(struct elf_phdr);
15091da177e4SLinus Torvalds 	elf->e_phnum = segs;
15101da177e4SLinus Torvalds }
15111da177e4SLinus Torvalds 
fill_elf_note_phdr(struct elf_phdr * phdr,int sz,loff_t offset)15128d6b5eeeSAndrew Morton static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, loff_t offset)
15131da177e4SLinus Torvalds {
15141da177e4SLinus Torvalds 	phdr->p_type = PT_NOTE;
15151da177e4SLinus Torvalds 	phdr->p_offset = offset;
15161da177e4SLinus Torvalds 	phdr->p_vaddr = 0;
15171da177e4SLinus Torvalds 	phdr->p_paddr = 0;
15181da177e4SLinus Torvalds 	phdr->p_filesz = sz;
15191da177e4SLinus Torvalds 	phdr->p_memsz = 0;
15201da177e4SLinus Torvalds 	phdr->p_flags = 0;
152160592fb6SFangrui Song 	phdr->p_align = 4;
15221da177e4SLinus Torvalds }
15231da177e4SLinus Torvalds 
fill_note(struct memelfnote * note,const char * name,int type,unsigned int sz,void * data)15241da177e4SLinus Torvalds static void fill_note(struct memelfnote *note, const char *name, int type,
15251da177e4SLinus Torvalds 		unsigned int sz, void *data)
15261da177e4SLinus Torvalds {
15271da177e4SLinus Torvalds 	note->name = name;
15281da177e4SLinus Torvalds 	note->type = type;
15291da177e4SLinus Torvalds 	note->datasz = sz;
15301da177e4SLinus Torvalds 	note->data = data;
15311da177e4SLinus Torvalds }
15321da177e4SLinus Torvalds 
15331da177e4SLinus Torvalds /*
1534f4e5cc2cSJesper Juhl  * fill up all the fields in prstatus from the given task struct, except
1535f4e5cc2cSJesper Juhl  * registers which need to be filled up separately.
15361da177e4SLinus Torvalds  */
fill_prstatus(struct elf_prstatus_common * prstatus,struct task_struct * p,long signr)1537f2485a2dSAl Viro static void fill_prstatus(struct elf_prstatus_common *prstatus,
15381da177e4SLinus Torvalds 		struct task_struct *p, long signr)
15391da177e4SLinus Torvalds {
15401da177e4SLinus Torvalds 	prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
15411da177e4SLinus Torvalds 	prstatus->pr_sigpend = p->pending.signal.sig[0];
15421da177e4SLinus Torvalds 	prstatus->pr_sighold = p->blocked.sig[0];
15433b34fc58SOleg Nesterov 	rcu_read_lock();
15443b34fc58SOleg Nesterov 	prstatus->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent));
15453b34fc58SOleg Nesterov 	rcu_read_unlock();
1546b488893aSPavel Emelyanov 	prstatus->pr_pid = task_pid_vnr(p);
1547b488893aSPavel Emelyanov 	prstatus->pr_pgrp = task_pgrp_vnr(p);
1548b488893aSPavel Emelyanov 	prstatus->pr_sid = task_session_vnr(p);
15491da177e4SLinus Torvalds 	if (thread_group_leader(p)) {
1550cd19c364SFrederic Weisbecker 		struct task_cputime cputime;
1551f06febc9SFrank Mayhar 
15521da177e4SLinus Torvalds 		/*
1553f06febc9SFrank Mayhar 		 * This is the record for the group leader.  It shows the
1554f06febc9SFrank Mayhar 		 * group-wide total, not its individual thread total.
15551da177e4SLinus Torvalds 		 */
1556cd19c364SFrederic Weisbecker 		thread_group_cputime(p, &cputime);
1557e2bb80d5SArnd Bergmann 		prstatus->pr_utime = ns_to_kernel_old_timeval(cputime.utime);
1558e2bb80d5SArnd Bergmann 		prstatus->pr_stime = ns_to_kernel_old_timeval(cputime.stime);
15591da177e4SLinus Torvalds 	} else {
1560cd19c364SFrederic Weisbecker 		u64 utime, stime;
15616fac4829SFrederic Weisbecker 
1562cd19c364SFrederic Weisbecker 		task_cputime(p, &utime, &stime);
1563e2bb80d5SArnd Bergmann 		prstatus->pr_utime = ns_to_kernel_old_timeval(utime);
1564e2bb80d5SArnd Bergmann 		prstatus->pr_stime = ns_to_kernel_old_timeval(stime);
15651da177e4SLinus Torvalds 	}
15665613fda9SFrederic Weisbecker 
1567e2bb80d5SArnd Bergmann 	prstatus->pr_cutime = ns_to_kernel_old_timeval(p->signal->cutime);
1568e2bb80d5SArnd Bergmann 	prstatus->pr_cstime = ns_to_kernel_old_timeval(p->signal->cstime);
15691da177e4SLinus Torvalds }
15701da177e4SLinus Torvalds 
fill_psinfo(struct elf_prpsinfo * psinfo,struct task_struct * p,struct mm_struct * mm)15711da177e4SLinus Torvalds static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
15721da177e4SLinus Torvalds 		       struct mm_struct *mm)
15731da177e4SLinus Torvalds {
1574c69e8d9cSDavid Howells 	const struct cred *cred;
1575a84a5059SGreg Kroah-Hartman 	unsigned int i, len;
15762f064a59SPeter Zijlstra 	unsigned int state;
15771da177e4SLinus Torvalds 
15781da177e4SLinus Torvalds 	/* first copy the parameters from user space */
15791da177e4SLinus Torvalds 	memset(psinfo, 0, sizeof(struct elf_prpsinfo));
15801da177e4SLinus Torvalds 
15811da177e4SLinus Torvalds 	len = mm->arg_end - mm->arg_start;
15821da177e4SLinus Torvalds 	if (len >= ELF_PRARGSZ)
15831da177e4SLinus Torvalds 		len = ELF_PRARGSZ-1;
15841da177e4SLinus Torvalds 	if (copy_from_user(&psinfo->pr_psargs,
15851da177e4SLinus Torvalds 		           (const char __user *)mm->arg_start, len))
15861da177e4SLinus Torvalds 		return -EFAULT;
15871da177e4SLinus Torvalds 	for(i = 0; i < len; i++)
15881da177e4SLinus Torvalds 		if (psinfo->pr_psargs[i] == 0)
15891da177e4SLinus Torvalds 			psinfo->pr_psargs[i] = ' ';
15901da177e4SLinus Torvalds 	psinfo->pr_psargs[len] = 0;
15911da177e4SLinus Torvalds 
15923b34fc58SOleg Nesterov 	rcu_read_lock();
15933b34fc58SOleg Nesterov 	psinfo->pr_ppid = task_pid_vnr(rcu_dereference(p->real_parent));
15943b34fc58SOleg Nesterov 	rcu_read_unlock();
1595b488893aSPavel Emelyanov 	psinfo->pr_pid = task_pid_vnr(p);
1596b488893aSPavel Emelyanov 	psinfo->pr_pgrp = task_pgrp_vnr(p);
1597b488893aSPavel Emelyanov 	psinfo->pr_sid = task_session_vnr(p);
15981da177e4SLinus Torvalds 
15992f064a59SPeter Zijlstra 	state = READ_ONCE(p->__state);
16002f064a59SPeter Zijlstra 	i = state ? ffz(~state) + 1 : 0;
16011da177e4SLinus Torvalds 	psinfo->pr_state = i;
160255148548SCarsten Otte 	psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i];
16031da177e4SLinus Torvalds 	psinfo->pr_zomb = psinfo->pr_sname == 'Z';
16041da177e4SLinus Torvalds 	psinfo->pr_nice = task_nice(p);
16051da177e4SLinus Torvalds 	psinfo->pr_flag = p->flags;
1606c69e8d9cSDavid Howells 	rcu_read_lock();
1607c69e8d9cSDavid Howells 	cred = __task_cred(p);
1608ebc887b2SEric W. Biederman 	SET_UID(psinfo->pr_uid, from_kuid_munged(cred->user_ns, cred->uid));
1609ebc887b2SEric W. Biederman 	SET_GID(psinfo->pr_gid, from_kgid_munged(cred->user_ns, cred->gid));
1610c69e8d9cSDavid Howells 	rcu_read_unlock();
161195af469cSYafang Shao 	get_task_comm(psinfo->pr_fname, p);
16121da177e4SLinus Torvalds 
16131da177e4SLinus Torvalds 	return 0;
16141da177e4SLinus Torvalds }
16151da177e4SLinus Torvalds 
fill_auxv_note(struct memelfnote * note,struct mm_struct * mm)16163aba481fSRoland McGrath static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
16173aba481fSRoland McGrath {
16183aba481fSRoland McGrath 	elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv;
16193aba481fSRoland McGrath 	int i = 0;
16203aba481fSRoland McGrath 	do
16213aba481fSRoland McGrath 		i += 2;
16223aba481fSRoland McGrath 	while (auxv[i - 2] != AT_NULL);
16233aba481fSRoland McGrath 	fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
16243aba481fSRoland McGrath }
16253aba481fSRoland McGrath 
fill_siginfo_note(struct memelfnote * note,user_siginfo_t * csigdata,const kernel_siginfo_t * siginfo)162649ae4d4bSDenys Vlasenko static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
1627ae7795bcSEric W. Biederman 		const kernel_siginfo_t *siginfo)
162849ae4d4bSDenys Vlasenko {
1629fa4751f4SEric W. Biederman 	copy_siginfo_to_external(csigdata, siginfo);
163049ae4d4bSDenys Vlasenko 	fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata);
163149ae4d4bSDenys Vlasenko }
163249ae4d4bSDenys Vlasenko 
16332aa362c4SDenys Vlasenko #define MAX_FILE_NOTE_SIZE (4*1024*1024)
16342aa362c4SDenys Vlasenko /*
16352aa362c4SDenys Vlasenko  * Format of NT_FILE note:
16362aa362c4SDenys Vlasenko  *
16372aa362c4SDenys Vlasenko  * long count     -- how many files are mapped
16382aa362c4SDenys Vlasenko  * long page_size -- units for file_ofs
16392aa362c4SDenys Vlasenko  * array of [COUNT] elements of
16402aa362c4SDenys Vlasenko  *   long start
16412aa362c4SDenys Vlasenko  *   long end
16422aa362c4SDenys Vlasenko  *   long file_ofs
16432aa362c4SDenys Vlasenko  * followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL...
16442aa362c4SDenys Vlasenko  */
fill_files_note(struct memelfnote * note,struct coredump_params * cprm)1645390031c9SEric W. Biederman static int fill_files_note(struct memelfnote *note, struct coredump_params *cprm)
16462aa362c4SDenys Vlasenko {
16472aa362c4SDenys Vlasenko 	unsigned count, size, names_ofs, remaining, n;
16482aa362c4SDenys Vlasenko 	user_long_t *data;
16492aa362c4SDenys Vlasenko 	user_long_t *start_end_ofs;
16502aa362c4SDenys Vlasenko 	char *name_base, *name_curpos;
1651390031c9SEric W. Biederman 	int i;
16522aa362c4SDenys Vlasenko 
16532aa362c4SDenys Vlasenko 	/* *Estimated* file count and total data size needed */
1654390031c9SEric W. Biederman 	count = cprm->vma_count;
165560c9d92fSAlexey Dobriyan 	if (count > UINT_MAX / 64)
165660c9d92fSAlexey Dobriyan 		return -EINVAL;
16572aa362c4SDenys Vlasenko 	size = count * 64;
16582aa362c4SDenys Vlasenko 
16592aa362c4SDenys Vlasenko 	names_ofs = (2 + 3 * count) * sizeof(data[0]);
16602aa362c4SDenys Vlasenko  alloc:
16612aa362c4SDenys Vlasenko 	if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */
166272023656SDan Aloni 		return -EINVAL;
16632aa362c4SDenys Vlasenko 	size = round_up(size, PAGE_SIZE);
16641fbede6eSAlexey Dobriyan 	/*
16651fbede6eSAlexey Dobriyan 	 * "size" can be 0 here legitimately.
16661fbede6eSAlexey Dobriyan 	 * Let it ENOMEM and omit NT_FILE section which will be empty anyway.
16671fbede6eSAlexey Dobriyan 	 */
166886a2bb5aSAlexey Dobriyan 	data = kvmalloc(size, GFP_KERNEL);
166986a2bb5aSAlexey Dobriyan 	if (ZERO_OR_NULL_PTR(data))
167072023656SDan Aloni 		return -ENOMEM;
16712aa362c4SDenys Vlasenko 
16722aa362c4SDenys Vlasenko 	start_end_ofs = data + 2;
16732aa362c4SDenys Vlasenko 	name_base = name_curpos = ((char *)data) + names_ofs;
16742aa362c4SDenys Vlasenko 	remaining = size - names_ofs;
16752aa362c4SDenys Vlasenko 	count = 0;
1676390031c9SEric W. Biederman 	for (i = 0; i < cprm->vma_count; i++) {
1677390031c9SEric W. Biederman 		struct core_vma_metadata *m = &cprm->vma_meta[i];
16782aa362c4SDenys Vlasenko 		struct file *file;
16792aa362c4SDenys Vlasenko 		const char *filename;
16802aa362c4SDenys Vlasenko 
1681390031c9SEric W. Biederman 		file = m->file;
16822aa362c4SDenys Vlasenko 		if (!file)
16832aa362c4SDenys Vlasenko 			continue;
16849bf39ab2SMiklos Szeredi 		filename = file_path(file, name_curpos, remaining);
16852aa362c4SDenys Vlasenko 		if (IS_ERR(filename)) {
16862aa362c4SDenys Vlasenko 			if (PTR_ERR(filename) == -ENAMETOOLONG) {
168786a2bb5aSAlexey Dobriyan 				kvfree(data);
16882aa362c4SDenys Vlasenko 				size = size * 5 / 4;
16892aa362c4SDenys Vlasenko 				goto alloc;
16902aa362c4SDenys Vlasenko 			}
16912aa362c4SDenys Vlasenko 			continue;
16922aa362c4SDenys Vlasenko 		}
16932aa362c4SDenys Vlasenko 
16949bf39ab2SMiklos Szeredi 		/* file_path() fills at the end, move name down */
16952aa362c4SDenys Vlasenko 		/* n = strlen(filename) + 1: */
16962aa362c4SDenys Vlasenko 		n = (name_curpos + remaining) - filename;
16972aa362c4SDenys Vlasenko 		remaining = filename - name_curpos;
16982aa362c4SDenys Vlasenko 		memmove(name_curpos, filename, n);
16992aa362c4SDenys Vlasenko 		name_curpos += n;
17002aa362c4SDenys Vlasenko 
1701390031c9SEric W. Biederman 		*start_end_ofs++ = m->start;
1702390031c9SEric W. Biederman 		*start_end_ofs++ = m->end;
1703390031c9SEric W. Biederman 		*start_end_ofs++ = m->pgoff;
17042aa362c4SDenys Vlasenko 		count++;
17052aa362c4SDenys Vlasenko 	}
17062aa362c4SDenys Vlasenko 
17072aa362c4SDenys Vlasenko 	/* Now we know exact count of files, can store it */
17082aa362c4SDenys Vlasenko 	data[0] = count;
17092aa362c4SDenys Vlasenko 	data[1] = PAGE_SIZE;
17102aa362c4SDenys Vlasenko 	/*
171103c6d723SAlexey Dobriyan 	 * Count usually is less than mm->map_count,
17122aa362c4SDenys Vlasenko 	 * we need to move filenames down.
17132aa362c4SDenys Vlasenko 	 */
1714390031c9SEric W. Biederman 	n = cprm->vma_count - count;
17152aa362c4SDenys Vlasenko 	if (n != 0) {
17162aa362c4SDenys Vlasenko 		unsigned shift_bytes = n * 3 * sizeof(data[0]);
17172aa362c4SDenys Vlasenko 		memmove(name_base - shift_bytes, name_base,
17182aa362c4SDenys Vlasenko 			name_curpos - name_base);
17192aa362c4SDenys Vlasenko 		name_curpos -= shift_bytes;
17202aa362c4SDenys Vlasenko 	}
17212aa362c4SDenys Vlasenko 
17222aa362c4SDenys Vlasenko 	size = name_curpos - (char *)data;
17232aa362c4SDenys Vlasenko 	fill_note(note, "CORE", NT_FILE, size, data);
172472023656SDan Aloni 	return 0;
17252aa362c4SDenys Vlasenko }
17262aa362c4SDenys Vlasenko 
17274206d3aaSRoland McGrath #include <linux/regset.h>
17284206d3aaSRoland McGrath 
17294206d3aaSRoland McGrath struct elf_thread_core_info {
17304206d3aaSRoland McGrath 	struct elf_thread_core_info *next;
17314206d3aaSRoland McGrath 	struct task_struct *task;
17324206d3aaSRoland McGrath 	struct elf_prstatus prstatus;
17335e01fdffSGustavo A. R. Silva 	struct memelfnote notes[];
17344206d3aaSRoland McGrath };
17354206d3aaSRoland McGrath 
17364206d3aaSRoland McGrath struct elf_note_info {
17374206d3aaSRoland McGrath 	struct elf_thread_core_info *thread;
17384206d3aaSRoland McGrath 	struct memelfnote psinfo;
173949ae4d4bSDenys Vlasenko 	struct memelfnote signote;
17404206d3aaSRoland McGrath 	struct memelfnote auxv;
17412aa362c4SDenys Vlasenko 	struct memelfnote files;
174249ae4d4bSDenys Vlasenko 	user_siginfo_t csigdata;
17434206d3aaSRoland McGrath 	size_t size;
17444206d3aaSRoland McGrath 	int thread_notes;
17454206d3aaSRoland McGrath };
17464206d3aaSRoland McGrath 
1747e92edb85SAl Viro #ifdef CORE_DUMP_USE_REGSET
1748d31472b6SRoland McGrath /*
1749d31472b6SRoland McGrath  * When a regset has a writeback hook, we call it on each thread before
1750d31472b6SRoland McGrath  * dumping user memory.  On register window machines, this makes sure the
1751d31472b6SRoland McGrath  * user memory backing the register data is up to date before we read it.
1752d31472b6SRoland McGrath  */
do_thread_regset_writeback(struct task_struct * task,const struct user_regset * regset)1753d31472b6SRoland McGrath static void do_thread_regset_writeback(struct task_struct *task,
1754d31472b6SRoland McGrath 				       const struct user_regset *regset)
1755d31472b6SRoland McGrath {
1756d31472b6SRoland McGrath 	if (regset->writeback)
1757d31472b6SRoland McGrath 		regset->writeback(task, regset, 1);
1758d31472b6SRoland McGrath }
1759d31472b6SRoland McGrath 
17600953f65dSH. J. Lu #ifndef PRSTATUS_SIZE
17618a00dd00SAl Viro #define PRSTATUS_SIZE sizeof(struct elf_prstatus)
17620953f65dSH. J. Lu #endif
17630953f65dSH. J. Lu 
17640953f65dSH. J. Lu #ifndef SET_PR_FPVALID
17658a00dd00SAl Viro #define SET_PR_FPVALID(S) ((S)->pr_fpvalid = 1)
17660953f65dSH. J. Lu #endif
17670953f65dSH. J. Lu 
fill_thread_core_info(struct elf_thread_core_info * t,const struct user_regset_view * view,long signr,struct elf_note_info * info)17684206d3aaSRoland McGrath static int fill_thread_core_info(struct elf_thread_core_info *t,
17694206d3aaSRoland McGrath 				 const struct user_regset_view *view,
1770dd664099SRick Edgecombe 				 long signr, struct elf_note_info *info)
17714206d3aaSRoland McGrath {
1772dd664099SRick Edgecombe 	unsigned int note_iter, view_iter;
17734206d3aaSRoland McGrath 
17744206d3aaSRoland McGrath 	/*
17754206d3aaSRoland McGrath 	 * NT_PRSTATUS is the one special case, because the regset data
17764206d3aaSRoland McGrath 	 * goes into the pr_reg field inside the note contents, rather
1777aa88054bSBaruch Siach 	 * than being the whole note contents.  We fill the regset in here.
17784206d3aaSRoland McGrath 	 * We assume that regset 0 is NT_PRSTATUS.
17794206d3aaSRoland McGrath 	 */
1780f2485a2dSAl Viro 	fill_prstatus(&t->prstatus.common, t->task, signr);
17818a00dd00SAl Viro 	regset_get(t->task, &view->regsets[0],
1782b4e9c954SAl Viro 		   sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);
17834206d3aaSRoland McGrath 
17844206d3aaSRoland McGrath 	fill_note(&t->notes[0], "CORE", NT_PRSTATUS,
17858a00dd00SAl Viro 		  PRSTATUS_SIZE, &t->prstatus);
1786dd664099SRick Edgecombe 	info->size += notesize(&t->notes[0]);
17874206d3aaSRoland McGrath 
1788d31472b6SRoland McGrath 	do_thread_regset_writeback(t->task, &view->regsets[0]);
1789d31472b6SRoland McGrath 
17904206d3aaSRoland McGrath 	/*
17914206d3aaSRoland McGrath 	 * Each other regset might generate a note too.  For each regset
1792dd664099SRick Edgecombe 	 * that has no core_note_type or is inactive, skip it.
17934206d3aaSRoland McGrath 	 */
1794dd664099SRick Edgecombe 	note_iter = 1;
1795dd664099SRick Edgecombe 	for (view_iter = 1; view_iter < view->n; ++view_iter) {
1796dd664099SRick Edgecombe 		const struct user_regset *regset = &view->regsets[view_iter];
1797b4e9c954SAl Viro 		int note_type = regset->core_note_type;
1798b4e9c954SAl Viro 		bool is_fpreg = note_type == NT_PRFPREG;
1799b4e9c954SAl Viro 		void *data;
18004206d3aaSRoland McGrath 		int ret;
1801b4e9c954SAl Viro 
1802b4e9c954SAl Viro 		do_thread_regset_writeback(t->task, regset);
1803b4e9c954SAl Viro 		if (!note_type) // not for coredumps
1804b4e9c954SAl Viro 			continue;
1805b4e9c954SAl Viro 		if (regset->active && regset->active(t->task, regset) <= 0)
1806b4e9c954SAl Viro 			continue;
1807b4e9c954SAl Viro 
1808b4e9c954SAl Viro 		ret = regset_get_alloc(t->task, regset, ~0U, &data);
1809b4e9c954SAl Viro 		if (ret < 0)
1810b4e9c954SAl Viro 			continue;
1811b4e9c954SAl Viro 
1812dd664099SRick Edgecombe 		if (WARN_ON_ONCE(note_iter >= info->thread_notes))
1813dd664099SRick Edgecombe 			break;
1814dd664099SRick Edgecombe 
1815b4e9c954SAl Viro 		if (is_fpreg)
18168a00dd00SAl Viro 			SET_PR_FPVALID(&t->prstatus);
1817b4e9c954SAl Viro 
1818dd664099SRick Edgecombe 		fill_note(&t->notes[note_iter], is_fpreg ? "CORE" : "LINUX",
1819b4e9c954SAl Viro 			  note_type, ret, data);
1820b4e9c954SAl Viro 
1821dd664099SRick Edgecombe 		info->size += notesize(&t->notes[note_iter]);
1822dd664099SRick Edgecombe 		note_iter++;
18234206d3aaSRoland McGrath 	}
18244206d3aaSRoland McGrath 
18254206d3aaSRoland McGrath 	return 1;
18264206d3aaSRoland McGrath }
1827e92edb85SAl Viro #else
fill_thread_core_info(struct elf_thread_core_info * t,const struct user_regset_view * view,long signr,struct elf_note_info * info)1828e92edb85SAl Viro static int fill_thread_core_info(struct elf_thread_core_info *t,
1829e92edb85SAl Viro 				 const struct user_regset_view *view,
1830e92edb85SAl Viro 				 long signr, struct elf_note_info *info)
1831e92edb85SAl Viro {
1832e92edb85SAl Viro 	struct task_struct *p = t->task;
1833e92edb85SAl Viro 	elf_fpregset_t *fpu;
1834e92edb85SAl Viro 
1835e92edb85SAl Viro 	fill_prstatus(&t->prstatus.common, p, signr);
1836e92edb85SAl Viro 	elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
1837e92edb85SAl Viro 
1838e92edb85SAl Viro 	fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
1839e92edb85SAl Viro 		  &(t->prstatus));
1840e92edb85SAl Viro 	info->size += notesize(&t->notes[0]);
1841e92edb85SAl Viro 
1842e92edb85SAl Viro 	fpu = kzalloc(sizeof(elf_fpregset_t), GFP_KERNEL);
1843e92edb85SAl Viro 	if (!fpu || !elf_core_copy_task_fpregs(p, fpu)) {
1844e92edb85SAl Viro 		kfree(fpu);
1845e92edb85SAl Viro 		return 1;
1846e92edb85SAl Viro 	}
1847e92edb85SAl Viro 
1848e92edb85SAl Viro 	t->prstatus.pr_fpvalid = 1;
1849e92edb85SAl Viro 	fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
1850e92edb85SAl Viro 	info->size += notesize(&t->notes[1]);
1851e92edb85SAl Viro 
1852e92edb85SAl Viro 	return 1;
1853e92edb85SAl Viro }
1854e92edb85SAl Viro #endif
18554206d3aaSRoland McGrath 
fill_note_info(struct elfhdr * elf,int phdrs,struct elf_note_info * info,struct coredump_params * cprm)18564206d3aaSRoland McGrath static int fill_note_info(struct elfhdr *elf, int phdrs,
18574206d3aaSRoland McGrath 			  struct elf_note_info *info,
18589ec7d323SEric W. Biederman 			  struct coredump_params *cprm)
18594206d3aaSRoland McGrath {
18604206d3aaSRoland McGrath 	struct task_struct *dump_task = current;
1861e92edb85SAl Viro 	const struct user_regset_view *view;
18624206d3aaSRoland McGrath 	struct elf_thread_core_info *t;
18634206d3aaSRoland McGrath 	struct elf_prpsinfo *psinfo;
186483914441SOleg Nesterov 	struct core_thread *ct;
18654206d3aaSRoland McGrath 
18664206d3aaSRoland McGrath 	psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
1867922ef161SAl Viro 	if (!psinfo)
18684206d3aaSRoland McGrath 		return 0;
1869e2dbe125SAmerigo Wang 	fill_note(&info->psinfo, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
1870e2dbe125SAmerigo Wang 
1871e92edb85SAl Viro #ifdef CORE_DUMP_USE_REGSET
1872e92edb85SAl Viro 	view = task_user_regset_view(dump_task);
1873e92edb85SAl Viro 
18744206d3aaSRoland McGrath 	/*
18754206d3aaSRoland McGrath 	 * Figure out how many notes we're going to need for each thread.
18764206d3aaSRoland McGrath 	 */
18774206d3aaSRoland McGrath 	info->thread_notes = 0;
1878922ef161SAl Viro 	for (int i = 0; i < view->n; ++i)
18794206d3aaSRoland McGrath 		if (view->regsets[i].core_note_type != 0)
18804206d3aaSRoland McGrath 			++info->thread_notes;
18814206d3aaSRoland McGrath 
18824206d3aaSRoland McGrath 	/*
18834206d3aaSRoland McGrath 	 * Sanity check.  We rely on regset 0 being in NT_PRSTATUS,
18844206d3aaSRoland McGrath 	 * since it is our one special case.
18854206d3aaSRoland McGrath 	 */
18864206d3aaSRoland McGrath 	if (unlikely(info->thread_notes == 0) ||
18874206d3aaSRoland McGrath 	    unlikely(view->regsets[0].core_note_type != NT_PRSTATUS)) {
18884206d3aaSRoland McGrath 		WARN_ON(1);
18894206d3aaSRoland McGrath 		return 0;
18904206d3aaSRoland McGrath 	}
18914206d3aaSRoland McGrath 
18924206d3aaSRoland McGrath 	/*
18934206d3aaSRoland McGrath 	 * Initialize the ELF file header.
18944206d3aaSRoland McGrath 	 */
18954206d3aaSRoland McGrath 	fill_elf_header(elf, phdrs,
1896d3330cf0SZhang Yanfei 			view->e_machine, view->e_flags);
1897e92edb85SAl Viro #else
1898e92edb85SAl Viro 	view = NULL;
1899e92edb85SAl Viro 	info->thread_notes = 2;
1900e92edb85SAl Viro 	fill_elf_header(elf, phdrs, ELF_ARCH, ELF_CORE_EFLAGS);
1901e92edb85SAl Viro #endif
19024206d3aaSRoland McGrath 
19034206d3aaSRoland McGrath 	/*
19044206d3aaSRoland McGrath 	 * Allocate a structure for each thread.
19054206d3aaSRoland McGrath 	 */
19064b0e21d6SAl Viro 	info->thread = kzalloc(offsetof(struct elf_thread_core_info,
19074b0e21d6SAl Viro 				     notes[info->thread_notes]),
19084b0e21d6SAl Viro 			    GFP_KERNEL);
19094b0e21d6SAl Viro 	if (unlikely(!info->thread))
19104b0e21d6SAl Viro 		return 0;
19114b0e21d6SAl Viro 
19124b0e21d6SAl Viro 	info->thread->task = dump_task;
19134b0e21d6SAl Viro 	for (ct = dump_task->signal->core_state->dumper.next; ct; ct = ct->next) {
19144206d3aaSRoland McGrath 		t = kzalloc(offsetof(struct elf_thread_core_info,
19154206d3aaSRoland McGrath 				     notes[info->thread_notes]),
191683914441SOleg Nesterov 			    GFP_KERNEL);
191783914441SOleg Nesterov 		if (unlikely(!t))
19184206d3aaSRoland McGrath 			return 0;
191983914441SOleg Nesterov 
192083914441SOleg Nesterov 		t->task = ct->task;
19214206d3aaSRoland McGrath 		t->next = info->thread->next;
19224206d3aaSRoland McGrath 		info->thread->next = t;
19234206d3aaSRoland McGrath 	}
19244206d3aaSRoland McGrath 
19254206d3aaSRoland McGrath 	/*
19264206d3aaSRoland McGrath 	 * Now fill in each thread's information.
19274206d3aaSRoland McGrath 	 */
19284206d3aaSRoland McGrath 	for (t = info->thread; t != NULL; t = t->next)
1929dd664099SRick Edgecombe 		if (!fill_thread_core_info(t, view, cprm->siginfo->si_signo, info))
19304206d3aaSRoland McGrath 			return 0;
19314206d3aaSRoland McGrath 
19324206d3aaSRoland McGrath 	/*
19334206d3aaSRoland McGrath 	 * Fill in the two process-wide notes.
19344206d3aaSRoland McGrath 	 */
19354206d3aaSRoland McGrath 	fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm);
19364206d3aaSRoland McGrath 	info->size += notesize(&info->psinfo);
19374206d3aaSRoland McGrath 
19389ec7d323SEric W. Biederman 	fill_siginfo_note(&info->signote, &info->csigdata, cprm->siginfo);
193949ae4d4bSDenys Vlasenko 	info->size += notesize(&info->signote);
194049ae4d4bSDenys Vlasenko 
19414206d3aaSRoland McGrath 	fill_auxv_note(&info->auxv, current->mm);
19424206d3aaSRoland McGrath 	info->size += notesize(&info->auxv);
19434206d3aaSRoland McGrath 
1944390031c9SEric W. Biederman 	if (fill_files_note(&info->files, cprm) == 0)
19452aa362c4SDenys Vlasenko 		info->size += notesize(&info->files);
19462aa362c4SDenys Vlasenko 
19474206d3aaSRoland McGrath 	return 1;
19484206d3aaSRoland McGrath }
19494206d3aaSRoland McGrath 
19504206d3aaSRoland McGrath /*
19514206d3aaSRoland McGrath  * Write all the notes for each thread.  When writing the first thread, the
19524206d3aaSRoland McGrath  * process-wide notes are interleaved after the first thread-specific note.
19534206d3aaSRoland McGrath  */
write_note_info(struct elf_note_info * info,struct coredump_params * cprm)19544206d3aaSRoland McGrath static int write_note_info(struct elf_note_info *info,
1955ecc8c772SAl Viro 			   struct coredump_params *cprm)
19564206d3aaSRoland McGrath {
1957b219e25fSFabian Frederick 	bool first = true;
19584206d3aaSRoland McGrath 	struct elf_thread_core_info *t = info->thread;
19594206d3aaSRoland McGrath 
19604206d3aaSRoland McGrath 	do {
19614206d3aaSRoland McGrath 		int i;
19624206d3aaSRoland McGrath 
1963ecc8c772SAl Viro 		if (!writenote(&t->notes[0], cprm))
19644206d3aaSRoland McGrath 			return 0;
19654206d3aaSRoland McGrath 
1966ecc8c772SAl Viro 		if (first && !writenote(&info->psinfo, cprm))
19674206d3aaSRoland McGrath 			return 0;
1968ecc8c772SAl Viro 		if (first && !writenote(&info->signote, cprm))
196949ae4d4bSDenys Vlasenko 			return 0;
1970ecc8c772SAl Viro 		if (first && !writenote(&info->auxv, cprm))
19714206d3aaSRoland McGrath 			return 0;
197272023656SDan Aloni 		if (first && info->files.data &&
1973ecc8c772SAl Viro 				!writenote(&info->files, cprm))
19742aa362c4SDenys Vlasenko 			return 0;
19754206d3aaSRoland McGrath 
19764206d3aaSRoland McGrath 		for (i = 1; i < info->thread_notes; ++i)
19774206d3aaSRoland McGrath 			if (t->notes[i].data &&
1978ecc8c772SAl Viro 			    !writenote(&t->notes[i], cprm))
19794206d3aaSRoland McGrath 				return 0;
19804206d3aaSRoland McGrath 
1981b219e25fSFabian Frederick 		first = false;
19824206d3aaSRoland McGrath 		t = t->next;
19834206d3aaSRoland McGrath 	} while (t);
19844206d3aaSRoland McGrath 
19854206d3aaSRoland McGrath 	return 1;
19864206d3aaSRoland McGrath }
19874206d3aaSRoland McGrath 
free_note_info(struct elf_note_info * info)19884206d3aaSRoland McGrath static void free_note_info(struct elf_note_info *info)
19894206d3aaSRoland McGrath {
19904206d3aaSRoland McGrath 	struct elf_thread_core_info *threads = info->thread;
19914206d3aaSRoland McGrath 	while (threads) {
19924206d3aaSRoland McGrath 		unsigned int i;
19934206d3aaSRoland McGrath 		struct elf_thread_core_info *t = threads;
19944206d3aaSRoland McGrath 		threads = t->next;
19954206d3aaSRoland McGrath 		WARN_ON(t->notes[0].data && t->notes[0].data != &t->prstatus);
19964206d3aaSRoland McGrath 		for (i = 1; i < info->thread_notes; ++i)
19974206d3aaSRoland McGrath 			kfree(t->notes[i].data);
19984206d3aaSRoland McGrath 		kfree(t);
19994206d3aaSRoland McGrath 	}
20004206d3aaSRoland McGrath 	kfree(info->psinfo.data);
200186a2bb5aSAlexey Dobriyan 	kvfree(info->files.data);
20024206d3aaSRoland McGrath }
20034206d3aaSRoland McGrath 
fill_extnum_info(struct elfhdr * elf,struct elf_shdr * shdr4extnum,elf_addr_t e_shoff,int segs)20048d9032bbSDaisuke HATAYAMA static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
20058d9032bbSDaisuke HATAYAMA 			     elf_addr_t e_shoff, int segs)
20068d9032bbSDaisuke HATAYAMA {
20078d9032bbSDaisuke HATAYAMA 	elf->e_shoff = e_shoff;
20088d9032bbSDaisuke HATAYAMA 	elf->e_shentsize = sizeof(*shdr4extnum);
20098d9032bbSDaisuke HATAYAMA 	elf->e_shnum = 1;
20108d9032bbSDaisuke HATAYAMA 	elf->e_shstrndx = SHN_UNDEF;
20118d9032bbSDaisuke HATAYAMA 
20128d9032bbSDaisuke HATAYAMA 	memset(shdr4extnum, 0, sizeof(*shdr4extnum));
20138d9032bbSDaisuke HATAYAMA 
20148d9032bbSDaisuke HATAYAMA 	shdr4extnum->sh_type = SHT_NULL;
20158d9032bbSDaisuke HATAYAMA 	shdr4extnum->sh_size = elf->e_shnum;
20168d9032bbSDaisuke HATAYAMA 	shdr4extnum->sh_link = elf->e_shstrndx;
20178d9032bbSDaisuke HATAYAMA 	shdr4extnum->sh_info = segs;
20188d9032bbSDaisuke HATAYAMA }
20198d9032bbSDaisuke HATAYAMA 
20201da177e4SLinus Torvalds /*
20211da177e4SLinus Torvalds  * Actual dumper
20221da177e4SLinus Torvalds  *
20231da177e4SLinus Torvalds  * This is a two-pass process; first we find the offsets of the bits,
20241da177e4SLinus Torvalds  * and then they are actually written out.  If we run out of core limit
20251da177e4SLinus Torvalds  * we just truncate.
20261da177e4SLinus Torvalds  */
elf_core_dump(struct coredump_params * cprm)2027f6151dfeSMasami Hiramatsu static int elf_core_dump(struct coredump_params *cprm)
20281da177e4SLinus Torvalds {
20291da177e4SLinus Torvalds 	int has_dumped = 0;
203095c5436aSEric W. Biederman 	int segs, i;
2031225a3f53SAlexey Dobriyan 	struct elfhdr elf;
2032cdc3d562SAl Viro 	loff_t offset = 0, dataoff;
203372023656SDan Aloni 	struct elf_note_info info = { };
203493eb211eSDaisuke HATAYAMA 	struct elf_phdr *phdr4note = NULL;
20358d9032bbSDaisuke HATAYAMA 	struct elf_shdr *shdr4extnum = NULL;
20368d9032bbSDaisuke HATAYAMA 	Elf_Half e_phnum;
20378d9032bbSDaisuke HATAYAMA 	elf_addr_t e_shoff;
20381da177e4SLinus Torvalds 
2039341c87bfSKAMEZAWA Hiroyuki 	/*
2040341c87bfSKAMEZAWA Hiroyuki 	 * The number of segs are recored into ELF header as 16bit value.
2041341c87bfSKAMEZAWA Hiroyuki 	 * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
2042341c87bfSKAMEZAWA Hiroyuki 	 */
204319e183b5SCatalin Marinas 	segs = cprm->vma_count + elf_core_extra_phdrs(cprm);
2044f47aef55SRoland McGrath 
20458d9032bbSDaisuke HATAYAMA 	/* for notes section */
20468d9032bbSDaisuke HATAYAMA 	segs++;
20478d9032bbSDaisuke HATAYAMA 
20488d9032bbSDaisuke HATAYAMA 	/* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
20498d9032bbSDaisuke HATAYAMA 	 * this, kernel supports extended numbering. Have a look at
20508d9032bbSDaisuke HATAYAMA 	 * include/linux/elf.h for further information. */
20518d9032bbSDaisuke HATAYAMA 	e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
20528d9032bbSDaisuke HATAYAMA 
20533aba481fSRoland McGrath 	/*
20543aba481fSRoland McGrath 	 * Collect all the non-memory information about the process for the
20553aba481fSRoland McGrath 	 * notes.  This also sets up the file header.
20563aba481fSRoland McGrath 	 */
20579ec7d323SEric W. Biederman 	if (!fill_note_info(&elf, e_phnum, &info, cprm))
2058d2530b43SChristoph Hellwig 		goto end_coredump;
20591da177e4SLinus Torvalds 
20601da177e4SLinus Torvalds 	has_dumped = 1;
20611da177e4SLinus Torvalds 
206270e79866SAlexey Dobriyan 	offset += sizeof(elf);				/* ELF header */
20638d9032bbSDaisuke HATAYAMA 	offset += segs * sizeof(struct elf_phdr);	/* Program headers */
20641da177e4SLinus Torvalds 
20651da177e4SLinus Torvalds 	/* Write notes phdr entry */
20661da177e4SLinus Torvalds 	{
206738ba2f11SAl Viro 		size_t sz = info.size;
20681da177e4SLinus Torvalds 
2069c39ab6deSEric W. Biederman 		/* For cell spufs */
2070e5501492SMichael Ellerman 		sz += elf_coredump_extra_notes_size();
2071bf1ab978SDwayne Grant McConnell 
207293eb211eSDaisuke HATAYAMA 		phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
207393eb211eSDaisuke HATAYAMA 		if (!phdr4note)
2074088e7af7SDaisuke HATAYAMA 			goto end_coredump;
207593eb211eSDaisuke HATAYAMA 
207693eb211eSDaisuke HATAYAMA 		fill_elf_note_phdr(phdr4note, sz, offset);
207793eb211eSDaisuke HATAYAMA 		offset += sz;
20781da177e4SLinus Torvalds 	}
20791da177e4SLinus Torvalds 
20801da177e4SLinus Torvalds 	dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
20811da177e4SLinus Torvalds 
208295c5436aSEric W. Biederman 	offset += cprm->vma_data_size;
208319e183b5SCatalin Marinas 	offset += elf_core_extra_data_size(cprm);
20848d9032bbSDaisuke HATAYAMA 	e_shoff = offset;
20858d9032bbSDaisuke HATAYAMA 
20868d9032bbSDaisuke HATAYAMA 	if (e_phnum == PN_XNUM) {
20878d9032bbSDaisuke HATAYAMA 		shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
20888d9032bbSDaisuke HATAYAMA 		if (!shdr4extnum)
20898d9032bbSDaisuke HATAYAMA 			goto end_coredump;
2090225a3f53SAlexey Dobriyan 		fill_extnum_info(&elf, shdr4extnum, e_shoff, segs);
20918d9032bbSDaisuke HATAYAMA 	}
20928d9032bbSDaisuke HATAYAMA 
20938d9032bbSDaisuke HATAYAMA 	offset = dataoff;
20948d9032bbSDaisuke HATAYAMA 
2095225a3f53SAlexey Dobriyan 	if (!dump_emit(cprm, &elf, sizeof(elf)))
209693eb211eSDaisuke HATAYAMA 		goto end_coredump;
209793eb211eSDaisuke HATAYAMA 
2098ecc8c772SAl Viro 	if (!dump_emit(cprm, phdr4note, sizeof(*phdr4note)))
209993eb211eSDaisuke HATAYAMA 		goto end_coredump;
210093eb211eSDaisuke HATAYAMA 
21011da177e4SLinus Torvalds 	/* Write program headers for segments dump */
210295c5436aSEric W. Biederman 	for (i = 0; i < cprm->vma_count; i++) {
210395c5436aSEric W. Biederman 		struct core_vma_metadata *meta = cprm->vma_meta + i;
21041da177e4SLinus Torvalds 		struct elf_phdr phdr;
21051da177e4SLinus Torvalds 
21061da177e4SLinus Torvalds 		phdr.p_type = PT_LOAD;
21071da177e4SLinus Torvalds 		phdr.p_offset = offset;
2108a07279c9SJann Horn 		phdr.p_vaddr = meta->start;
21091da177e4SLinus Torvalds 		phdr.p_paddr = 0;
2110a07279c9SJann Horn 		phdr.p_filesz = meta->dump_size;
2111a07279c9SJann Horn 		phdr.p_memsz = meta->end - meta->start;
21121da177e4SLinus Torvalds 		offset += phdr.p_filesz;
2113a07279c9SJann Horn 		phdr.p_flags = 0;
2114a07279c9SJann Horn 		if (meta->flags & VM_READ)
2115a07279c9SJann Horn 			phdr.p_flags |= PF_R;
2116a07279c9SJann Horn 		if (meta->flags & VM_WRITE)
2117f4e5cc2cSJesper Juhl 			phdr.p_flags |= PF_W;
2118a07279c9SJann Horn 		if (meta->flags & VM_EXEC)
2119f4e5cc2cSJesper Juhl 			phdr.p_flags |= PF_X;
21201da177e4SLinus Torvalds 		phdr.p_align = ELF_EXEC_PAGESIZE;
21211da177e4SLinus Torvalds 
2122ecc8c772SAl Viro 		if (!dump_emit(cprm, &phdr, sizeof(phdr)))
2123088e7af7SDaisuke HATAYAMA 			goto end_coredump;
21241da177e4SLinus Torvalds 	}
21251da177e4SLinus Torvalds 
2126506f21c5SAl Viro 	if (!elf_core_write_extra_phdrs(cprm, offset))
21271fcccbacSDaisuke HATAYAMA 		goto end_coredump;
21281da177e4SLinus Torvalds 
21291da177e4SLinus Torvalds 	/* write out the notes section */
2130ecc8c772SAl Viro 	if (!write_note_info(&info, cprm))
21311da177e4SLinus Torvalds 		goto end_coredump;
21321da177e4SLinus Torvalds 
2133c39ab6deSEric W. Biederman 	/* For cell spufs */
2134cdc3d562SAl Viro 	if (elf_coredump_extra_notes_write(cprm))
2135e5501492SMichael Ellerman 		goto end_coredump;
2136bf1ab978SDwayne Grant McConnell 
2137d025c9dbSAndi Kleen 	/* Align to page */
2138d0f1088bSAl Viro 	dump_skip_to(cprm, dataoff);
21391da177e4SLinus Torvalds 
214095c5436aSEric W. Biederman 	for (i = 0; i < cprm->vma_count; i++) {
214195c5436aSEric W. Biederman 		struct core_vma_metadata *meta = cprm->vma_meta + i;
2142a07279c9SJann Horn 
2143a07279c9SJann Horn 		if (!dump_user_range(cprm, meta->start, meta->dump_size))
21441da177e4SLinus Torvalds 			goto end_coredump;
21451da177e4SLinus Torvalds 	}
21461da177e4SLinus Torvalds 
2147aa3e7eafSAl Viro 	if (!elf_core_write_extra_data(cprm))
21481fcccbacSDaisuke HATAYAMA 		goto end_coredump;
21491da177e4SLinus Torvalds 
21508d9032bbSDaisuke HATAYAMA 	if (e_phnum == PN_XNUM) {
215113046eceSAl Viro 		if (!dump_emit(cprm, shdr4extnum, sizeof(*shdr4extnum)))
21528d9032bbSDaisuke HATAYAMA 			goto end_coredump;
21538d9032bbSDaisuke HATAYAMA 	}
21548d9032bbSDaisuke HATAYAMA 
21551da177e4SLinus Torvalds end_coredump:
21563aba481fSRoland McGrath 	free_note_info(&info);
21578d9032bbSDaisuke HATAYAMA 	kfree(shdr4extnum);
215893eb211eSDaisuke HATAYAMA 	kfree(phdr4note);
21591da177e4SLinus Torvalds 	return has_dumped;
21601da177e4SLinus Torvalds }
21611da177e4SLinus Torvalds 
2162698ba7b5SChristoph Hellwig #endif		/* CONFIG_ELF_CORE */
21631da177e4SLinus Torvalds 
init_elf_binfmt(void)21641da177e4SLinus Torvalds static int __init init_elf_binfmt(void)
21651da177e4SLinus Torvalds {
21668fc3dc5aSAl Viro 	register_binfmt(&elf_format);
21678fc3dc5aSAl Viro 	return 0;
21681da177e4SLinus Torvalds }
21691da177e4SLinus Torvalds 
exit_elf_binfmt(void)21701da177e4SLinus Torvalds static void __exit exit_elf_binfmt(void)
21711da177e4SLinus Torvalds {
21721da177e4SLinus Torvalds 	/* Remove the COFF and ELF loaders. */
21731da177e4SLinus Torvalds 	unregister_binfmt(&elf_format);
21741da177e4SLinus Torvalds }
21751da177e4SLinus Torvalds 
21761da177e4SLinus Torvalds core_initcall(init_elf_binfmt);
21771da177e4SLinus Torvalds module_exit(exit_elf_binfmt);
21789e1a3ce0SKees Cook 
21799e1a3ce0SKees Cook #ifdef CONFIG_BINFMT_ELF_KUNIT_TEST
21809e1a3ce0SKees Cook #include "binfmt_elf_test.c"
21819e1a3ce0SKees Cook #endif
2182