diff options
author | Kawai, Hidehiro <hidehiro.kawai.ez@hitachi.com> | 2007-07-19 04:48:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:47 -0400 |
commit | a1b59e802f846b6b0e057507386068fcc6dff442 (patch) | |
tree | 1ad51ffa807774986595e56b6fac3525b6a285ac /fs/binfmt_elf.c | |
parent | 3cb4a0bb1e773e3c41800b33a3f7dab32bd06c64 (diff) |
coredump masking: ELF: enable core dump filtering
This patch enables core dump filtering for ELF-formatted core file.
Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: David Howells <dhowells@redhat.com>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r-- | fs/binfmt_elf.c | 30 |
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 | */ |
1265 | static int maydump(struct vm_area_struct *vma) | 1265 | static 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; |