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; |