2144 lines · 57.1 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* * linux/fs/binfmt_elf.c * * These are the functions used to load ELF format executables as used * on SVr4 machines.  Information on the format may be found in the book * "UNIX SYSTEM V RELEASE 4 Programmers Guide: Ansi C and Programming Support * Tools". * * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com). */ #include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/log2.h>#include <linux/mm.h>#include <linux/mman.h>#include <linux/errno.h>#include <linux/signal.h>#include <linux/binfmts.h>#include <linux/string.h>#include <linux/file.h>#include <linux/slab.h>#include <linux/personality.h>#include <linux/elfcore.h>#include <linux/init.h>#include <linux/highuid.h>#include <linux/compiler.h>#include <linux/highmem.h>#include <linux/hugetlb.h>#include <linux/pagemap.h>#include <linux/vmalloc.h>#include <linux/security.h>#include <linux/random.h>#include <linux/elf.h>#include <linux/elf-randomize.h>#include <linux/utsname.h>#include <linux/coredump.h>#include <linux/sched.h>#include <linux/sched/coredump.h>#include <linux/sched/task_stack.h>#include <linux/sched/cputime.h>#include <linux/sizes.h>#include <linux/types.h>#include <linux/cred.h>#include <linux/dax.h>#include <linux/uaccess.h>#include <uapi/linux/rseq.h>#include <linux/rseq.h>#include <asm/param.h>#include <asm/page.h> #ifndef ELF_COMPAT#define ELF_COMPAT 0#endif #ifndef user_long_t#define user_long_t long#endif#ifndef user_siginfo_t#define user_siginfo_t siginfo_t#endif /* That's for binfmt_elf_fdpic to deal with */#ifndef elf_check_fdpic#define elf_check_fdpic(ex) false#endif static int load_elf_binary(struct linux_binprm *bprm); /* * If we don't support core dumping, then supply a NULL so we * don't even try. */#ifdef CONFIG_ELF_COREstatic int elf_core_dump(struct coredump_params *cprm);#else#define elf_core_dump	NULL#endif #if ELF_EXEC_PAGESIZE > PAGE_SIZE#define ELF_MIN_ALIGN	ELF_EXEC_PAGESIZE#else#define ELF_MIN_ALIGN	PAGE_SIZE#endif #ifndef ELF_CORE_EFLAGS#define ELF_CORE_EFLAGS	0#endif #define ELF_PAGESTART(_v) ((_v) & ~(int)(ELF_MIN_ALIGN-1))#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))#define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1)) static struct linux_binfmt elf_format = {	.module		= THIS_MODULE,	.load_binary	= load_elf_binary,#ifdef CONFIG_COREDUMP	.core_dump	= elf_core_dump,	.min_coredump	= ELF_EXEC_PAGESIZE,#endif}; #define BAD_ADDR(x) (unlikely((unsigned long)(x) >= TASK_SIZE)) static inline void elf_coredump_set_mm_eflags(struct mm_struct *mm, u32 flags){#ifdef CONFIG_ARCH_HAS_ELF_CORE_EFLAGS	mm->saved_e_flags = flags;#endif} static inline u32 elf_coredump_get_mm_eflags(struct mm_struct *mm, u32 flags){#ifdef CONFIG_ARCH_HAS_ELF_CORE_EFLAGS	flags = mm->saved_e_flags;#endif	return flags;} /* * We need to explicitly zero any trailing portion of the page that follows * p_filesz when it ends before the page ends (e.g. bss), otherwise this * memory will contain the junk from the file that should not be present. */static int padzero(unsigned long address){	unsigned long nbyte; 	nbyte = ELF_PAGEOFFSET(address);	if (nbyte) {		nbyte = ELF_MIN_ALIGN - nbyte;		if (clear_user((void __user *)address, nbyte))			return -EFAULT;	}	return 0;} /* Let's use some macros to make this stack manipulation a little clearer */#ifdef CONFIG_STACK_GROWSUP#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) + (items))#define STACK_ROUND(sp, items) \	((15 + (unsigned long) ((sp) + (items))) &~ 15UL)#define STACK_ALLOC(sp, len) ({ \	elf_addr_t __user *old_sp = (elf_addr_t __user *)sp; sp += len; \	old_sp; })#else#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) - (items))#define STACK_ROUND(sp, items) \	(((unsigned long) (sp - items)) &~ 15UL)#define STACK_ALLOC(sp, len) (sp -= len)#endif #ifndef ELF_BASE_PLATFORM/* * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture. * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value * will be copied to the user stack in the same manner as AT_PLATFORM. */#define ELF_BASE_PLATFORM NULL#endif static intcreate_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,		unsigned long interp_load_addr,		unsigned long e_entry, unsigned long phdr_addr){	struct mm_struct *mm = current->mm;	unsigned long p = bprm->p;	int argc = bprm->argc;	int envc = bprm->envc;	elf_addr_t __user *sp;	elf_addr_t __user *u_platform;	elf_addr_t __user *u_base_platform;	elf_addr_t __user *u_rand_bytes;	const char *k_platform = ELF_PLATFORM;	const char *k_base_platform = ELF_BASE_PLATFORM;	unsigned char k_rand_bytes[16];	int items;	elf_addr_t *elf_info;	int ei_index;	const struct cred *cred = current_cred();	struct vm_area_struct *vma; 	/*	 * In some cases (e.g. Hyper-Threading), we want to avoid L1	 * evictions by the processes running on the same package. One	 * thing we can do is to shuffle the initial stack for them.	 */ 	p = arch_align_stack(p); 	/*	 * If this architecture has a platform capability string, copy it	 * to userspace.  In some cases (Sparc), this info is impossible	 * for userspace to get any other way, in others (i386) it is	 * merely difficult.	 */	u_platform = NULL;	if (k_platform) {		size_t len = strlen(k_platform) + 1; 		u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);		if (copy_to_user(u_platform, k_platform, len))			return -EFAULT;	} 	/*	 * If this architecture has a "base" platform capability	 * string, copy it to userspace.	 */	u_base_platform = NULL;	if (k_base_platform) {		size_t len = strlen(k_base_platform) + 1; 		u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);		if (copy_to_user(u_base_platform, k_base_platform, len))			return -EFAULT;	} 	/*	 * Generate 16 random bytes for userspace PRNG seeding.	 */	get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));	u_rand_bytes = (elf_addr_t __user *)		       STACK_ALLOC(p, sizeof(k_rand_bytes));	if (copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))		return -EFAULT; 	/* Create the ELF interpreter info */	elf_info = (elf_addr_t *)mm->saved_auxv;	/* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */#define NEW_AUX_ENT(id, val) \	do { \		*elf_info++ = id; \		*elf_info++ = val; \	} while (0) #ifdef ARCH_DLINFO	/*	 * ARCH_DLINFO must come first so PPC can do its special alignment of	 * AUXV.	 * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT() in	 * ARCH_DLINFO changes	 */	ARCH_DLINFO;#endif	NEW_AUX_ENT(AT_HWCAP, ELF_HWCAP);	NEW_AUX_ENT(AT_PAGESZ, ELF_EXEC_PAGESIZE);	NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC);	NEW_AUX_ENT(AT_PHDR, phdr_addr);	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);	NEW_AUX_ENT(AT_BASE, interp_load_addr);	NEW_AUX_ENT(AT_FLAGS, bprm_at_flags(bprm));	NEW_AUX_ENT(AT_ENTRY, e_entry);	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));	NEW_AUX_ENT(AT_GID, from_kgid_munged(cred->user_ns, cred->gid));	NEW_AUX_ENT(AT_EGID, from_kgid_munged(cred->user_ns, cred->egid));	NEW_AUX_ENT(AT_SECURE, bprm->secureexec);	NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes);#ifdef ELF_HWCAP2	NEW_AUX_ENT(AT_HWCAP2, ELF_HWCAP2);#endif#ifdef ELF_HWCAP3	NEW_AUX_ENT(AT_HWCAP3, ELF_HWCAP3);#endif#ifdef ELF_HWCAP4	NEW_AUX_ENT(AT_HWCAP4, ELF_HWCAP4);#endif	NEW_AUX_ENT(AT_EXECFN, bprm->exec);	if (k_platform) {		NEW_AUX_ENT(AT_PLATFORM,			    (elf_addr_t)(unsigned long)u_platform);	}	if (k_base_platform) {		NEW_AUX_ENT(AT_BASE_PLATFORM,			    (elf_addr_t)(unsigned long)u_base_platform);	}	if (bprm->have_execfd) {		NEW_AUX_ENT(AT_EXECFD, bprm->execfd);	}#ifdef CONFIG_RSEQ	NEW_AUX_ENT(AT_RSEQ_FEATURE_SIZE, offsetof(struct rseq, end));	NEW_AUX_ENT(AT_RSEQ_ALIGN, rseq_alloc_align());#endif#undef NEW_AUX_ENT	/* AT_NULL is zero; clear the rest too */	memset(elf_info, 0, (char *)mm->saved_auxv +			sizeof(mm->saved_auxv) - (char *)elf_info); 	/* And advance past the AT_NULL entry.  */	elf_info += 2; 	ei_index = elf_info - (elf_addr_t *)mm->saved_auxv;	sp = STACK_ADD(p, ei_index); 	items = (argc + 1) + (envc + 1) + 1;	bprm->p = STACK_ROUND(sp, items); 	/* Point sp at the lowest address on the stack */#ifdef CONFIG_STACK_GROWSUP	sp = (elf_addr_t __user *)bprm->p - items - ei_index;	bprm->exec = (unsigned long)sp; /* XXX: PARISC HACK */#else	sp = (elf_addr_t __user *)bprm->p;#endif  	/*	 * Grow the stack manually; some architectures have a limit on how	 * far ahead a user-space access may be in order to grow the stack.	 */	if (mmap_write_lock_killable(mm))		return -EINTR;	vma = find_extend_vma_locked(mm, bprm->p);	mmap_write_unlock(mm);	if (!vma)		return -EFAULT; 	/* Now, let's put argc (and argv, envp if appropriate) on the stack */	if (put_user(argc, sp++))		return -EFAULT; 	/* Populate list of argv pointers back to argv strings. */	p = mm->arg_end = mm->arg_start;	while (argc-- > 0) {		size_t len;		if (put_user((elf_addr_t)p, sp++))			return -EFAULT;		len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);		if (!len || len > MAX_ARG_STRLEN)			return -EINVAL;		p += len;	}	if (put_user(0, sp++))		return -EFAULT;	mm->arg_end = p; 	/* Populate list of envp pointers back to envp strings. */	mm->env_end = mm->env_start = p;	while (envc-- > 0) {		size_t len;		if (put_user((elf_addr_t)p, sp++))			return -EFAULT;		len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);		if (!len || len > MAX_ARG_STRLEN)			return -EINVAL;		p += len;	}	if (put_user(0, sp++))		return -EFAULT;	mm->env_end = p; 	/* Put the elf_info on the stack in the right place.  */	if (copy_to_user(sp, mm->saved_auxv, ei_index * sizeof(elf_addr_t)))		return -EFAULT;	return 0;} /* * Map "eppnt->p_filesz" bytes from "filep" offset "eppnt->p_offset" * into memory at "addr". (Note that p_filesz is rounded up to the * next page, so any extra bytes from the file must be wiped.) */static unsigned long elf_map(struct file *filep, unsigned long addr,		const struct elf_phdr *eppnt, int prot, int type,		unsigned long total_size){	unsigned long map_addr;	unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);	unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);	addr = ELF_PAGESTART(addr);	size = ELF_PAGEALIGN(size); 	/* mmap() will return -EINVAL if given a zero size, but a	 * segment with zero filesize is perfectly valid */	if (!size)		return addr; 	/*	* total_size is the size of the ELF (interpreter) image.	* The _first_ mmap needs to know the full size, otherwise	* randomization might put this image into an overlapping	* position with the ELF binary image. (since size < total_size)	* So we first map the 'big' image - and unmap the remainder at	* the end. (which unmap is needed for ELF images with holes.)	*/	if (total_size) {		total_size = ELF_PAGEALIGN(total_size);		map_addr = vm_mmap(filep, addr, total_size, prot, type, off);		if (!BAD_ADDR(map_addr))			vm_munmap(map_addr+size, total_size-size);	} else		map_addr = vm_mmap(filep, addr, size, prot, type, off); 	if ((type & MAP_FIXED_NOREPLACE) &&	    PTR_ERR((void *)map_addr) == -EEXIST)		pr_info("%d (%s): Uhuuh, elf segment at %px requested but the memory is mapped already\n",			task_pid_nr(current), current->comm, (void *)addr); 	return(map_addr);} /* * Map "eppnt->p_filesz" bytes from "filep" offset "eppnt->p_offset" * into memory at "addr". Memory from "p_filesz" through "p_memsz" * rounded up to the next page is zeroed. */static unsigned long elf_load(struct file *filep, unsigned long addr,		const struct elf_phdr *eppnt, int prot, int type,		unsigned long total_size){	unsigned long zero_start, zero_end;	unsigned long map_addr; 	if (eppnt->p_filesz) {		map_addr = elf_map(filep, addr, eppnt, prot, type, total_size);		if (BAD_ADDR(map_addr))			return map_addr;		if (eppnt->p_memsz > eppnt->p_filesz) {			zero_start = map_addr + ELF_PAGEOFFSET(eppnt->p_vaddr) +				eppnt->p_filesz;			zero_end = map_addr + ELF_PAGEOFFSET(eppnt->p_vaddr) +				eppnt->p_memsz; 			/*			 * Zero the end of the last mapped page but ignore			 * any errors if the segment isn't writable.			 */			if (padzero(zero_start) && (prot & PROT_WRITE))				return -EFAULT;		}	} else {		map_addr = zero_start = ELF_PAGESTART(addr);		zero_end = zero_start + ELF_PAGEOFFSET(eppnt->p_vaddr) +			eppnt->p_memsz;	}	if (eppnt->p_memsz > eppnt->p_filesz) {		/*		 * Map the last of the segment.		 * If the header is requesting these pages to be		 * executable, honour that (ppc32 needs this).		 */		int error; 		zero_start = ELF_PAGEALIGN(zero_start);		zero_end = ELF_PAGEALIGN(zero_end); 		error = vm_brk_flags(zero_start, zero_end - zero_start,				     prot & PROT_EXEC);		if (error)			map_addr = error;	}	return map_addr;} static unsigned long total_mapping_size(const struct elf_phdr *phdr, int nr){	elf_addr_t min_addr = -1;	elf_addr_t max_addr = 0;	bool pt_load = false;	int i; 	for (i = 0; i < nr; i++) {		if (phdr[i].p_type == PT_LOAD) {			min_addr = min(min_addr, ELF_PAGESTART(phdr[i].p_vaddr));			max_addr = max(max_addr, phdr[i].p_vaddr + phdr[i].p_memsz);			pt_load = true;		}	}	return pt_load ? (max_addr - min_addr) : 0;} static int elf_read(struct file *file, void *buf, size_t len, loff_t pos){	ssize_t rv; 	rv = kernel_read(file, buf, len, &pos);	if (unlikely(rv != len)) {		return (rv < 0) ? rv : -EIO;	}	return 0;} static unsigned long maximum_alignment(struct elf_phdr *cmds, int nr){	unsigned long alignment = 0;	int i; 	for (i = 0; i < nr; i++) {		if (cmds[i].p_type == PT_LOAD) {			unsigned long p_align = cmds[i].p_align; 			/* skip non-power of two alignments as invalid */			if (!is_power_of_2(p_align))				continue;			alignment = max(alignment, p_align);

Lines 1–500 of 2144.