aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-08 09:26:08 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-11-09 00:16:26 -0500
commit9b56d54380adb5fef71f687109bbd6f8413d694f (patch)
tree006cd31736372a9f7c9d4e6d7b99a8dd1748d49a /fs
parent2507a4fbd48a96bc4236e584252635f8539079df (diff)
dump_skip(): dump_seek() replacement taking coredump_params
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/binfmt_aout.c2
-rw-r--r--fs/binfmt_elf.c4
-rw-r--r--fs/binfmt_elf_fdpic.c11
-rw-r--r--fs/coredump.c43
4 files changed, 20 insertions, 40 deletions
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index a4f847f77234..ca0ba15a7306 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -87,7 +87,7 @@ static int aout_core_dump(struct coredump_params *cprm)
87 if (!dump_emit(cprm, &dump, sizeof(dump))) 87 if (!dump_emit(cprm, &dump, sizeof(dump)))
88 goto end_coredump; 88 goto end_coredump;
89/* Now dump all of the user data. Include malloced stuff as well */ 89/* Now dump all of the user data. Include malloced stuff as well */
90 if (!dump_seek(cprm->file, PAGE_SIZE - sizeof(dump))) 90 if (!dump_skip(cprm, PAGE_SIZE - sizeof(dump)))
91 goto end_coredump; 91 goto end_coredump;
92/* now we start writing out the user space info */ 92/* now we start writing out the user space info */
93 set_fs(USER_DS); 93 set_fs(USER_DS);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 4f7dda9d86b5..c56ae3264a65 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -2162,7 +2162,7 @@ static int elf_core_dump(struct coredump_params *cprm)
2162 goto end_coredump; 2162 goto end_coredump;
2163 2163
2164 /* Align to page */ 2164 /* Align to page */
2165 if (!dump_seek(cprm->file, dataoff - cprm->written)) 2165 if (!dump_skip(cprm, dataoff - cprm->written))
2166 goto end_coredump; 2166 goto end_coredump;
2167 2167
2168 for (vma = first_vma(current, gate_vma); vma != NULL; 2168 for (vma = first_vma(current, gate_vma); vma != NULL;
@@ -2183,7 +2183,7 @@ static int elf_core_dump(struct coredump_params *cprm)
2183 kunmap(page); 2183 kunmap(page);
2184 page_cache_release(page); 2184 page_cache_release(page);
2185 } else 2185 } else
2186 stop = !dump_seek(cprm->file, PAGE_SIZE); 2186 stop = !dump_skip(cprm, PAGE_SIZE);
2187 if (stop) 2187 if (stop)
2188 goto end_coredump; 2188 goto end_coredump;
2189 } 2189 }
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 70e299917898..a69fc4ae1c85 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1509,7 +1509,7 @@ static bool elf_fdpic_dump_segments(struct coredump_params *cprm)
1509 kunmap(page); 1509 kunmap(page);
1510 page_cache_release(page); 1510 page_cache_release(page);
1511 } else { 1511 } else {
1512 res = dump_seek(file, PAGE_SIZE); 1512 res = dump_skip(cprm, PAGE_SIZE);
1513 } 1513 }
1514 if (!res) 1514 if (!res)
1515 return false; 1515 return false;
@@ -1547,11 +1547,10 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1547 int has_dumped = 0; 1547 int has_dumped = 0;
1548 mm_segment_t fs; 1548 mm_segment_t fs;
1549 int segs; 1549 int segs;
1550 size_t size = 0;
1551 int i; 1550 int i;
1552 struct vm_area_struct *vma; 1551 struct vm_area_struct *vma;
1553 struct elfhdr *elf = NULL; 1552 struct elfhdr *elf = NULL;
1554 loff_t offset = 0, dataoff, foffset; 1553 loff_t offset = 0, dataoff;
1555 int numnote; 1554 int numnote;
1556 struct memelfnote *notes = NULL; 1555 struct memelfnote *notes = NULL;
1557 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */ 1556 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
@@ -1682,7 +1681,6 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1682 1681
1683 offset += sizeof(*elf); /* Elf header */ 1682 offset += sizeof(*elf); /* Elf header */
1684 offset += segs * sizeof(struct elf_phdr); /* Program headers */ 1683 offset += segs * sizeof(struct elf_phdr); /* Program headers */
1685 foffset = offset;
1686 1684
1687 /* Write notes phdr entry */ 1685 /* Write notes phdr entry */
1688 { 1686 {
@@ -1751,8 +1749,6 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1751 if (!elf_core_write_extra_phdrs(cprm, offset)) 1749 if (!elf_core_write_extra_phdrs(cprm, offset))
1752 goto end_coredump; 1750 goto end_coredump;
1753 1751
1754 size = cprm->written;
1755 cprm->written = foffset;
1756 /* write out the notes section */ 1752 /* write out the notes section */
1757 for (i = 0; i < numnote; i++) 1753 for (i = 0; i < numnote; i++)
1758 if (!writenote(notes + i, cprm)) 1754 if (!writenote(notes + i, cprm))
@@ -1768,10 +1764,9 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1768 goto end_coredump; 1764 goto end_coredump;
1769 } 1765 }
1770 1766
1771 if (!dump_seek(cprm->file, dataoff - cprm->written)) 1767 if (!dump_skip(cprm, dataoff - cprm->written))
1772 goto end_coredump; 1768 goto end_coredump;
1773 1769
1774 cprm->written = size;
1775 if (!elf_fdpic_dump_segments(cprm)) 1770 if (!elf_fdpic_dump_segments(cprm))
1776 goto end_coredump; 1771 goto end_coredump;
1777 1772
diff --git a/fs/coredump.c b/fs/coredump.c
index 2472ed9e682c..18baf2c009d4 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -685,14 +685,6 @@ fail:
685 * do on a core-file: use only these functions to write out all the 685 * do on a core-file: use only these functions to write out all the
686 * necessary info. 686 * necessary info.
687 */ 687 */
688int dump_write(struct file *file, const void *addr, int nr)
689{
690 return !dump_interrupted() &&
691 access_ok(VERIFY_READ, addr, nr) &&
692 file->f_op->write(file, addr, nr, &file->f_pos) == nr;
693}
694EXPORT_SYMBOL(dump_write);
695
696int dump_emit(struct coredump_params *cprm, const void *addr, int nr) 688int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
697{ 689{
698 struct file *file = cprm->file; 690 struct file *file = cprm->file;
@@ -714,32 +706,25 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
714} 706}
715EXPORT_SYMBOL(dump_emit); 707EXPORT_SYMBOL(dump_emit);
716 708
717int dump_seek(struct file *file, loff_t off) 709int dump_skip(struct coredump_params *cprm, size_t nr)
718{ 710{
719 int ret = 1; 711 static char zeroes[PAGE_SIZE];
720 712 struct file *file = cprm->file;
721 if (file->f_op->llseek && file->f_op->llseek != no_llseek) { 713 if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
714 if (cprm->written + nr > cprm->limit)
715 return 0;
722 if (dump_interrupted() || 716 if (dump_interrupted() ||
723 file->f_op->llseek(file, off, SEEK_CUR) < 0) 717 file->f_op->llseek(file, nr, SEEK_CUR) < 0)
724 return 0; 718 return 0;
719 cprm->written += nr;
720 return 1;
725 } else { 721 } else {
726 char *buf = (char *)get_zeroed_page(GFP_KERNEL); 722 while (nr > PAGE_SIZE) {
727 723 if (!dump_emit(cprm, zeroes, PAGE_SIZE))
728 if (!buf) 724 return 0;
729 return 0; 725 nr -= PAGE_SIZE;
730 while (off > 0) {
731 unsigned long n = off;
732
733 if (n > PAGE_SIZE)
734 n = PAGE_SIZE;
735 if (!dump_write(file, buf, n)) {
736 ret = 0;
737 break;
738 }
739 off -= n;
740 } 726 }
741 free_page((unsigned long)buf); 727 return dump_emit(cprm, zeroes, nr);
742 } 728 }
743 return ret;
744} 729}
745EXPORT_SYMBOL(dump_seek); 730EXPORT_SYMBOL(dump_skip);