diff options
author | Kawai, Hidehiro <hidehiro.kawai.ez@hitachi.com> | 2007-07-19 04:48:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:47 -0400 |
commit | ee78b0a61f0514ffc3d59257fbe6863b43477829 (patch) | |
tree | 2039f5c61595529991af01a3082559b8e1409762 /fs/binfmt_elf_fdpic.c | |
parent | e2e00906a06f7e74c49ca0ca85b960f270c83d5e (diff) |
coredump masking: ELF-FDPIC: enable core dump filtering
This patch enables core dump filtering for ELF-FDPIC-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_fdpic.c')
-rw-r--r-- | fs/binfmt_elf_fdpic.c | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 1a6c8e2eb1c5..2f5d8dbe676d 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1181,8 +1181,10 @@ static int dump_seek(struct file *file, loff_t off) | |||
1181 | * | 1181 | * |
1182 | * I think we should skip something. But I am not sure how. H.J. | 1182 | * I think we should skip something. But I am not sure how. H.J. |
1183 | */ | 1183 | */ |
1184 | static int maydump(struct vm_area_struct *vma) | 1184 | static int maydump(struct vm_area_struct *vma, unsigned long mm_flags) |
1185 | { | 1185 | { |
1186 | int dump_ok; | ||
1187 | |||
1186 | /* Do not dump I/O mapped devices or special mappings */ | 1188 | /* Do not dump I/O mapped devices or special mappings */ |
1187 | if (vma->vm_flags & (VM_IO | VM_RESERVED)) { | 1189 | if (vma->vm_flags & (VM_IO | VM_RESERVED)) { |
1188 | kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags); | 1190 | kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags); |
@@ -1197,27 +1199,35 @@ static int maydump(struct vm_area_struct *vma) | |||
1197 | return 0; | 1199 | return 0; |
1198 | } | 1200 | } |
1199 | 1201 | ||
1200 | /* Dump shared memory only if mapped from an anonymous file. */ | 1202 | /* By default, dump shared memory if mapped from an anonymous file. */ |
1201 | if (vma->vm_flags & VM_SHARED) { | 1203 | if (vma->vm_flags & VM_SHARED) { |
1202 | if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0) { | 1204 | if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0) { |
1203 | kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags); | 1205 | dump_ok = test_bit(MMF_DUMP_ANON_SHARED, &mm_flags); |
1204 | return 1; | 1206 | kdcore("%08lx: %08lx: %s (share)", vma->vm_start, |
1207 | vma->vm_flags, dump_ok ? "yes" : "no"); | ||
1208 | return dump_ok; | ||
1205 | } | 1209 | } |
1206 | 1210 | ||
1207 | kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags); | 1211 | dump_ok = test_bit(MMF_DUMP_MAPPED_SHARED, &mm_flags); |
1208 | return 0; | 1212 | kdcore("%08lx: %08lx: %s (share)", vma->vm_start, |
1213 | vma->vm_flags, dump_ok ? "yes" : "no"); | ||
1214 | return dump_ok; | ||
1209 | } | 1215 | } |
1210 | 1216 | ||
1211 | #ifdef CONFIG_MMU | 1217 | #ifdef CONFIG_MMU |
1212 | /* If it hasn't been written to, don't write it out */ | 1218 | /* By default, if it hasn't been written to, don't write it out */ |
1213 | if (!vma->anon_vma) { | 1219 | if (!vma->anon_vma) { |
1214 | kdcore("%08lx: %08lx: no (!anon)", vma->vm_start, vma->vm_flags); | 1220 | dump_ok = test_bit(MMF_DUMP_MAPPED_PRIVATE, &mm_flags); |
1215 | return 0; | 1221 | kdcore("%08lx: %08lx: %s (!anon)", vma->vm_start, |
1222 | vma->vm_flags, dump_ok ? "yes" : "no"); | ||
1223 | return dump_ok; | ||
1216 | } | 1224 | } |
1217 | #endif | 1225 | #endif |
1218 | 1226 | ||
1219 | kdcore("%08lx: %08lx: yes", vma->vm_start, vma->vm_flags); | 1227 | dump_ok = test_bit(MMF_DUMP_ANON_PRIVATE, &mm_flags); |
1220 | return 1; | 1228 | kdcore("%08lx: %08lx: %s", vma->vm_start, vma->vm_flags, |
1229 | dump_ok ? "yes" : "no"); | ||
1230 | return dump_ok; | ||
1221 | } | 1231 | } |
1222 | 1232 | ||
1223 | /* An ELF note in memory */ | 1233 | /* An ELF note in memory */ |
@@ -1457,14 +1467,14 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t) | |||
1457 | */ | 1467 | */ |
1458 | #ifdef CONFIG_MMU | 1468 | #ifdef CONFIG_MMU |
1459 | static int elf_fdpic_dump_segments(struct file *file, size_t *size, | 1469 | static int elf_fdpic_dump_segments(struct file *file, size_t *size, |
1460 | unsigned long *limit) | 1470 | unsigned long *limit, unsigned long mm_flags) |
1461 | { | 1471 | { |
1462 | struct vm_area_struct *vma; | 1472 | struct vm_area_struct *vma; |
1463 | 1473 | ||
1464 | for (vma = current->mm->mmap; vma; vma = vma->vm_next) { | 1474 | for (vma = current->mm->mmap; vma; vma = vma->vm_next) { |
1465 | unsigned long addr; | 1475 | unsigned long addr; |
1466 | 1476 | ||
1467 | if (!maydump(vma)) | 1477 | if (!maydump(vma, mm_flags)) |
1468 | continue; | 1478 | continue; |
1469 | 1479 | ||
1470 | for (addr = vma->vm_start; | 1480 | for (addr = vma->vm_start; |
@@ -1512,14 +1522,14 @@ end_coredump: | |||
1512 | */ | 1522 | */ |
1513 | #ifndef CONFIG_MMU | 1523 | #ifndef CONFIG_MMU |
1514 | static int elf_fdpic_dump_segments(struct file *file, size_t *size, | 1524 | static int elf_fdpic_dump_segments(struct file *file, size_t *size, |
1515 | unsigned long *limit) | 1525 | unsigned long *limit, unsigned long mm_flags) |
1516 | { | 1526 | { |
1517 | struct vm_list_struct *vml; | 1527 | struct vm_list_struct *vml; |
1518 | 1528 | ||
1519 | for (vml = current->mm->context.vmlist; vml; vml = vml->next) { | 1529 | for (vml = current->mm->context.vmlist; vml; vml = vml->next) { |
1520 | struct vm_area_struct *vma = vml->vma; | 1530 | struct vm_area_struct *vma = vml->vma; |
1521 | 1531 | ||
1522 | if (!maydump(vma)) | 1532 | if (!maydump(vma, mm_flags)) |
1523 | continue; | 1533 | continue; |
1524 | 1534 | ||
1525 | if ((*size += PAGE_SIZE) > *limit) | 1535 | if ((*size += PAGE_SIZE) > *limit) |
@@ -1570,6 +1580,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1570 | struct vm_list_struct *vml; | 1580 | struct vm_list_struct *vml; |
1571 | #endif | 1581 | #endif |
1572 | elf_addr_t *auxv; | 1582 | elf_addr_t *auxv; |
1583 | unsigned long mm_flags; | ||
1573 | 1584 | ||
1574 | /* | 1585 | /* |
1575 | * We no longer stop all VM operations. | 1586 | * We no longer stop all VM operations. |
@@ -1707,6 +1718,13 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1707 | /* Page-align dumped data */ | 1718 | /* Page-align dumped data */ |
1708 | dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); | 1719 | dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); |
1709 | 1720 | ||
1721 | /* | ||
1722 | * We must use the same mm->flags while dumping core to avoid | ||
1723 | * inconsistency between the program headers and bodies, otherwise an | ||
1724 | * unusable core file can be generated. | ||
1725 | */ | ||
1726 | mm_flags = current->mm->flags; | ||
1727 | |||
1710 | /* write program headers for segments dump */ | 1728 | /* write program headers for segments dump */ |
1711 | for ( | 1729 | for ( |
1712 | #ifdef CONFIG_MMU | 1730 | #ifdef CONFIG_MMU |
@@ -1728,7 +1746,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1728 | phdr.p_offset = offset; | 1746 | phdr.p_offset = offset; |
1729 | phdr.p_vaddr = vma->vm_start; | 1747 | phdr.p_vaddr = vma->vm_start; |
1730 | phdr.p_paddr = 0; | 1748 | phdr.p_paddr = 0; |
1731 | phdr.p_filesz = maydump(vma) ? sz : 0; | 1749 | phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0; |
1732 | phdr.p_memsz = sz; | 1750 | phdr.p_memsz = sz; |
1733 | offset += phdr.p_filesz; | 1751 | offset += phdr.p_filesz; |
1734 | phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; | 1752 | phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; |
@@ -1762,7 +1780,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1762 | 1780 | ||
1763 | DUMP_SEEK(dataoff); | 1781 | DUMP_SEEK(dataoff); |
1764 | 1782 | ||
1765 | if (elf_fdpic_dump_segments(file, current->mm, &size, &limit) < 0) | 1783 | if (elf_fdpic_dump_segments(file, &size, &limit, mm_flags) < 0) |
1766 | goto end_coredump; | 1784 | goto end_coredump; |
1767 | 1785 | ||
1768 | #ifdef ELF_CORE_WRITE_EXTRA_DATA | 1786 | #ifdef ELF_CORE_WRITE_EXTRA_DATA |