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, ¬e, 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