diff options
Diffstat (limited to 'fs/binfmt_elf.c')
| -rw-r--r-- | fs/binfmt_elf.c | 37 | 
1 files changed, 31 insertions, 6 deletions
| diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index bcb884e2d613..504b6eee50a9 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -712,7 +712,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)  		goto out_free_dentry;  	/* OK, This is the point of no return */ -	current->flags &= ~PF_FORKNOEXEC;  	current->mm->def_flags = def_flags;  	/* Do this immediately, since STACK_TOP as used in setup_arg_pages @@ -934,7 +933,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)  #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */  	install_exec_creds(bprm); -	current->flags &= ~PF_FORKNOEXEC;  	retval = create_elf_tables(bprm, &loc->elf_ex,  			  load_addr, interp_load_addr);  	if (retval < 0) { @@ -1095,6 +1093,29 @@ out:   */  /* + * The purpose of always_dump_vma() is to make sure that special kernel mappings + * that are useful for post-mortem analysis are included in every core dump. + * In that way we ensure that the core dump is fully interpretable later + * without matching up the same kernel and hardware config to see what PC values + * meant. These special mappings include - vDSO, vsyscall, and other + * architecture specific mappings + */ +static bool always_dump_vma(struct vm_area_struct *vma) +{ +	/* Any vsyscall mappings? */ +	if (vma == get_gate_vma(vma->vm_mm)) +		return true; +	/* +	 * arch_vma_name() returns non-NULL for special architecture mappings, +	 * such as vDSO sections. +	 */ +	if (arch_vma_name(vma)) +		return true; + +	return false; +} + +/*   * Decide what to dump of a segment, part, all or none.   */  static unsigned long vma_dump_size(struct vm_area_struct *vma, @@ -1102,10 +1123,13 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,  {  #define FILTER(type)	(mm_flags & (1UL << MMF_DUMP_##type)) -	/* The vma can be set up to tell us the answer directly.  */ -	if (vma->vm_flags & VM_ALWAYSDUMP) +	/* always dump the vdso and vsyscall sections */ +	if (always_dump_vma(vma))  		goto whole; +	if (vma->vm_flags & VM_NODUMP) +		return 0; +  	/* Hugetlb memory check */  	if (vma->vm_flags & VM_HUGETLB) {  		if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED)) @@ -1421,7 +1445,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,  	for (i = 1; i < view->n; ++i) {  		const struct user_regset *regset = &view->regsets[i];  		do_thread_regset_writeback(t->task, regset); -		if (regset->core_note_type && +		if (regset->core_note_type && regset->get &&  		    (!regset->active || regset->active(t->task, regset))) {  			int ret;  			size_t size = regset->n * regset->size; @@ -2077,7 +2101,8 @@ out:  static int __init init_elf_binfmt(void)  { -	return register_binfmt(&elf_format); +	register_binfmt(&elf_format); +	return 0;  }  static void __exit exit_elf_binfmt(void) | 
