aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf_fdpic.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-05 18:58:47 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-11-09 00:16:24 -0500
commite6c1baa9b562ca296d57178c44f3894795d13d32 (patch)
treeef29d210911b277acfe22953bc75d0fb4c8a5852 /fs/binfmt_elf_fdpic.c
parent13046ece9625f96fafb0cff0b9b95a586b53b553 (diff)
convert the rest of binfmt_elf_fdpic to dump_emit()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/binfmt_elf_fdpic.c')
-rw-r--r--fs/binfmt_elf_fdpic.c110
1 files changed, 31 insertions, 79 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 77bf7e33e706..70e299917898 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1267,35 +1267,23 @@ static int notesize(struct memelfnote *en)
1267 1267
1268/* #define DEBUG */ 1268/* #define DEBUG */
1269 1269
1270#define DUMP_WRITE(addr, nr, foffset) \ 1270static int alignfile(struct coredump_params *cprm)
1271 do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0)
1272
1273static int alignfile(struct file *file, loff_t *foffset)
1274{ 1271{
1275 static const char buf[4] = { 0, }; 1272 static const char buf[4] = { 0, };
1276 DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset); 1273 return dump_emit(cprm, buf, roundup(cprm->written, 4) - cprm->written);
1277 return 1;
1278} 1274}
1279 1275
1280static int writenote(struct memelfnote *men, struct file *file, 1276static int writenote(struct memelfnote *men, struct coredump_params *cprm)
1281 loff_t *foffset)
1282{ 1277{
1283 struct elf_note en; 1278 struct elf_note en;
1284 en.n_namesz = strlen(men->name) + 1; 1279 en.n_namesz = strlen(men->name) + 1;
1285 en.n_descsz = men->datasz; 1280 en.n_descsz = men->datasz;
1286 en.n_type = men->type; 1281 en.n_type = men->type;
1287 1282
1288 DUMP_WRITE(&en, sizeof(en), foffset); 1283 return dump_emit(cprm, &en, sizeof(en)) &&
1289 DUMP_WRITE(men->name, en.n_namesz, foffset); 1284 dump_emit(cprm, men->name, en.n_namesz) && alignfile(cprm) &&
1290 if (!alignfile(file, foffset)) 1285 dump_emit(cprm, men->data, men->datasz) && alignfile(cprm);
1291 return 0;
1292 DUMP_WRITE(men->data, men->datasz, foffset);
1293 if (!alignfile(file, foffset))
1294 return 0;
1295
1296 return 1;
1297} 1286}
1298#undef DUMP_WRITE
1299 1287
1300static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) 1288static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs)
1301{ 1289{
@@ -1500,66 +1488,40 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
1500/* 1488/*
1501 * dump the segments for an MMU process 1489 * dump the segments for an MMU process
1502 */ 1490 */
1503#ifdef CONFIG_MMU 1491static bool elf_fdpic_dump_segments(struct coredump_params *cprm)
1504static int elf_fdpic_dump_segments(struct file *file, size_t *size,
1505 unsigned long *limit, unsigned long mm_flags)
1506{ 1492{
1507 struct vm_area_struct *vma; 1493 struct vm_area_struct *vma;
1508 int err = 0;
1509 1494
1510 for (vma = current->mm->mmap; vma; vma = vma->vm_next) { 1495 for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
1511 unsigned long addr; 1496 unsigned long addr;
1512 1497
1513 if (!maydump(vma, mm_flags)) 1498 if (!maydump(vma, cprm->mm_flags))
1514 continue; 1499 continue;
1515 1500
1501#ifdef CONFIG_MMU
1516 for (addr = vma->vm_start; addr < vma->vm_end; 1502 for (addr = vma->vm_start; addr < vma->vm_end;
1517 addr += PAGE_SIZE) { 1503 addr += PAGE_SIZE) {
1504 bool res;
1518 struct page *page = get_dump_page(addr); 1505 struct page *page = get_dump_page(addr);
1519 if (page) { 1506 if (page) {
1520 void *kaddr = kmap(page); 1507 void *kaddr = kmap(page);
1521 *size += PAGE_SIZE; 1508 res = dump_emit(cprm, kaddr, PAGE_SIZE);
1522 if (*size > *limit)
1523 err = -EFBIG;
1524 else if (!dump_write(file, kaddr, PAGE_SIZE))
1525 err = -EIO;
1526 kunmap(page); 1509 kunmap(page);
1527 page_cache_release(page); 1510 page_cache_release(page);
1528 } else if (!dump_seek(file, PAGE_SIZE)) 1511 } else {
1529 err = -EFBIG; 1512 res = dump_seek(file, PAGE_SIZE);
1530 if (err) 1513 }
1531 goto out; 1514 if (!res)
1515 return false;
1532 } 1516 }
1533 } 1517#else
1534out: 1518 if (!dump_emit(cprm, (void *) vma->vm_start,
1535 return err;
1536}
1537#endif
1538
1539/*
1540 * dump the segments for a NOMMU process
1541 */
1542#ifndef CONFIG_MMU
1543static int elf_fdpic_dump_segments(struct file *file, size_t *size,
1544 unsigned long *limit, unsigned long mm_flags)
1545{
1546 struct vm_area_struct *vma;
1547
1548 for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
1549 if (!maydump(vma, mm_flags))
1550 continue;
1551
1552 if ((*size += PAGE_SIZE) > *limit)
1553 return -EFBIG;
1554
1555 if (!dump_write(file, (void *) vma->vm_start,
1556 vma->vm_end - vma->vm_start)) 1519 vma->vm_end - vma->vm_start))
1557 return -EIO; 1520 return false;
1521#endif
1558 } 1522 }
1559 1523 return true;
1560 return 0;
1561} 1524}
1562#endif
1563 1525
1564static size_t elf_core_vma_data_size(unsigned long mm_flags) 1526static size_t elf_core_vma_data_size(unsigned long mm_flags)
1565{ 1527{
@@ -1755,13 +1717,10 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1755 1717
1756 offset = dataoff; 1718 offset = dataoff;
1757 1719
1758 size += sizeof(*elf); 1720 if (!dump_emit(cprm, elf, sizeof(*elf)))
1759 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
1760 goto end_coredump; 1721 goto end_coredump;
1761 1722
1762 size += sizeof(*phdr4note); 1723 if (!dump_emit(cprm, phdr4note, sizeof(*phdr4note)))
1763 if (size > cprm->limit
1764 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
1765 goto end_coredump; 1724 goto end_coredump;
1766 1725
1767 /* write program headers for segments dump */ 1726 /* write program headers for segments dump */
@@ -1785,20 +1744,18 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1785 phdr.p_flags |= PF_X; 1744 phdr.p_flags |= PF_X;
1786 phdr.p_align = ELF_EXEC_PAGESIZE; 1745 phdr.p_align = ELF_EXEC_PAGESIZE;
1787 1746
1788 size += sizeof(phdr); 1747 if (!dump_emit(cprm, &phdr, sizeof(phdr)))
1789 if (size > cprm->limit
1790 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
1791 goto end_coredump; 1748 goto end_coredump;
1792 } 1749 }
1793 1750
1794 cprm->written = size;
1795 if (!elf_core_write_extra_phdrs(cprm, offset)) 1751 if (!elf_core_write_extra_phdrs(cprm, offset))
1796 goto end_coredump; 1752 goto end_coredump;
1797 1753
1798 size = cprm->written; 1754 size = cprm->written;
1755 cprm->written = foffset;
1799 /* write out the notes section */ 1756 /* write out the notes section */
1800 for (i = 0; i < numnote; i++) 1757 for (i = 0; i < numnote; i++)
1801 if (!writenote(notes + i, cprm->file, &foffset)) 1758 if (!writenote(notes + i, cprm))
1802 goto end_coredump; 1759 goto end_coredump;
1803 1760
1804 /* write out the thread status notes section */ 1761 /* write out the thread status notes section */
@@ -1807,27 +1764,22 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1807 list_entry(t, struct elf_thread_status, list); 1764 list_entry(t, struct elf_thread_status, list);
1808 1765
1809 for (i = 0; i < tmp->num_notes; i++) 1766 for (i = 0; i < tmp->num_notes; i++)
1810 if (!writenote(&tmp->notes[i], cprm->file, &foffset)) 1767 if (!writenote(&tmp->notes[i], cprm))
1811 goto end_coredump; 1768 goto end_coredump;
1812 } 1769 }
1813 1770
1814 if (!dump_seek(cprm->file, dataoff - foffset)) 1771 if (!dump_seek(cprm->file, dataoff - cprm->written))
1815 goto end_coredump; 1772 goto end_coredump;
1816 1773
1817 if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit, 1774 cprm->written = size;
1818 cprm->mm_flags) < 0) 1775 if (!elf_fdpic_dump_segments(cprm))
1819 goto end_coredump; 1776 goto end_coredump;
1820 1777
1821 cprm->written = size;
1822 if (!elf_core_write_extra_data(cprm)) 1778 if (!elf_core_write_extra_data(cprm))
1823 goto end_coredump; 1779 goto end_coredump;
1824 size = cprm->written;
1825 1780
1826 if (e_phnum == PN_XNUM) { 1781 if (e_phnum == PN_XNUM) {
1827 size += sizeof(*shdr4extnum); 1782 if (!dump_emit(cprm, shdr4extnum, sizeof(*shdr4extnum)))
1828 if (size > cprm->limit
1829 || !dump_write(cprm->file, shdr4extnum,
1830 sizeof(*shdr4extnum)))
1831 goto end_coredump; 1783 goto end_coredump;
1832 } 1784 }
1833 1785