diff options
Diffstat (limited to 'fs/binfmt_elf.c')
| -rw-r--r-- | fs/binfmt_elf.c | 27 | 
1 files changed, 16 insertions, 11 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index c1a499599b7..6fc49b6ed93 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1856,6 +1856,7 @@ static int elf_core_dump(struct coredump_params *cprm)  	loff_t offset = 0, dataoff, foffset;  	unsigned long mm_flags;  	struct elf_note_info info; +	struct elf_phdr *phdr4note = NULL;  	/*  	 * We no longer stop all VM operations. @@ -1898,28 +1899,22 @@ static int elf_core_dump(struct coredump_params *cprm)  	fs = get_fs();  	set_fs(KERNEL_DS); -	size += sizeof(*elf); -	if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf))) -		goto end_coredump; -  	offset += sizeof(*elf);				/* Elf header */  	offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */  	foffset = offset;  	/* Write notes phdr entry */  	{ -		struct elf_phdr phdr;  		size_t sz = get_note_info_size(&info);  		sz += elf_coredump_extra_notes_size(); -		fill_elf_note_phdr(&phdr, sz, offset); -		offset += sz; - -		size += sizeof(phdr); -		if (size > cprm->limit -		    || !dump_write(cprm->file, &phdr, sizeof(phdr))) +		phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL); +		if (!phdr4note)  			goto end_coredump; + +		fill_elf_note_phdr(phdr4note, sz, offset); +		offset += sz;  	}  	dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); @@ -1931,6 +1926,15 @@ static int elf_core_dump(struct coredump_params *cprm)  	 */  	mm_flags = current->mm->flags; +	size += sizeof(*elf); +	if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf))) +		goto end_coredump; + +	size += sizeof(*phdr4note); +	if (size > cprm->limit +	    || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note))) +		goto end_coredump; +  	/* Write program headers for segments dump */  	for (vma = first_vma(current, gate_vma); vma != NULL;  			vma = next_vma(vma, gate_vma)) { @@ -2004,6 +2008,7 @@ end_coredump:  cleanup:  	free_note_info(&info); +	kfree(phdr4note);  	kfree(elf);  out:  	return has_dumped;  |