aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 295cbaa0e58a..ba24cb2ff6ce 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1262,7 +1262,7 @@ static int dump_seek(struct file *file, loff_t off)
1262 * 1262 *
1263 * I think we should skip something. But I am not sure how. H.J. 1263 * I think we should skip something. But I am not sure how. H.J.
1264 */ 1264 */
1265static int maydump(struct vm_area_struct *vma) 1265static int maydump(struct vm_area_struct *vma, unsigned long mm_flags)
1266{ 1266{
1267 /* The vma can be set up to tell us the answer directly. */ 1267 /* The vma can be set up to tell us the answer directly. */
1268 if (vma->vm_flags & VM_ALWAYSDUMP) 1268 if (vma->vm_flags & VM_ALWAYSDUMP)
@@ -1272,15 +1272,19 @@ static int maydump(struct vm_area_struct *vma)
1272 if (vma->vm_flags & (VM_IO | VM_RESERVED)) 1272 if (vma->vm_flags & (VM_IO | VM_RESERVED))
1273 return 0; 1273 return 0;
1274 1274
1275 /* Dump shared memory only if mapped from an anonymous file. */ 1275 /* By default, dump shared memory if mapped from an anonymous file. */
1276 if (vma->vm_flags & VM_SHARED) 1276 if (vma->vm_flags & VM_SHARED) {
1277 return vma->vm_file->f_path.dentry->d_inode->i_nlink == 0; 1277 if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0)
1278 return test_bit(MMF_DUMP_ANON_SHARED, &mm_flags);
1279 else
1280 return test_bit(MMF_DUMP_MAPPED_SHARED, &mm_flags);
1281 }
1278 1282
1279 /* If it hasn't been written to, don't write it out */ 1283 /* By default, if it hasn't been written to, don't write it out. */
1280 if (!vma->anon_vma) 1284 if (!vma->anon_vma)
1281 return 0; 1285 return test_bit(MMF_DUMP_MAPPED_PRIVATE, &mm_flags);
1282 1286
1283 return 1; 1287 return test_bit(MMF_DUMP_ANON_PRIVATE, &mm_flags);
1284} 1288}
1285 1289
1286/* An ELF note in memory */ 1290/* An ELF note in memory */
@@ -1572,6 +1576,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1572#endif 1576#endif
1573 int thread_status_size = 0; 1577 int thread_status_size = 0;
1574 elf_addr_t *auxv; 1578 elf_addr_t *auxv;
1579 unsigned long mm_flags;
1575#ifdef ELF_CORE_WRITE_EXTRA_NOTES 1580#ifdef ELF_CORE_WRITE_EXTRA_NOTES
1576 int extra_notes_size; 1581 int extra_notes_size;
1577#endif 1582#endif
@@ -1715,6 +1720,13 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1715 1720
1716 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1721 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1717 1722
1723 /*
1724 * We must use the same mm->flags while dumping core to avoid
1725 * inconsistency between the program headers and bodies, otherwise an
1726 * unusable core file can be generated.
1727 */
1728 mm_flags = current->mm->flags;
1729
1718 /* Write program headers for segments dump */ 1730 /* Write program headers for segments dump */
1719 for (vma = first_vma(current, gate_vma); vma != NULL; 1731 for (vma = first_vma(current, gate_vma); vma != NULL;
1720 vma = next_vma(vma, gate_vma)) { 1732 vma = next_vma(vma, gate_vma)) {
@@ -1727,7 +1739,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1727 phdr.p_offset = offset; 1739 phdr.p_offset = offset;
1728 phdr.p_vaddr = vma->vm_start; 1740 phdr.p_vaddr = vma->vm_start;
1729 phdr.p_paddr = 0; 1741 phdr.p_paddr = 0;
1730 phdr.p_filesz = maydump(vma) ? sz : 0; 1742 phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0;
1731 phdr.p_memsz = sz; 1743 phdr.p_memsz = sz;
1732 offset += phdr.p_filesz; 1744 offset += phdr.p_filesz;
1733 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1745 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -1771,7 +1783,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1771 vma = next_vma(vma, gate_vma)) { 1783 vma = next_vma(vma, gate_vma)) {
1772 unsigned long addr; 1784 unsigned long addr;
1773 1785
1774 if (!maydump(vma)) 1786 if (!maydump(vma, mm_flags))
1775 continue; 1787 continue;
1776 1788
1777 for (addr = vma->vm_start; 1789 for (addr = vma->vm_start;