diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-10-05 18:58:47 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-11-09 00:16:24 -0500 |
commit | e6c1baa9b562ca296d57178c44f3894795d13d32 (patch) | |
tree | ef29d210911b277acfe22953bc75d0fb4c8a5852 /fs/binfmt_elf_fdpic.c | |
parent | 13046ece9625f96fafb0cff0b9b95a586b53b553 (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.c | 110 |
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) \ | 1270 | static int alignfile(struct coredump_params *cprm) |
1271 | do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0) | ||
1272 | |||
1273 | static 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 | ||
1280 | static int writenote(struct memelfnote *men, struct file *file, | 1276 | static 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 | ||
1300 | static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) | 1288 | static 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 | 1491 | static bool elf_fdpic_dump_segments(struct coredump_params *cprm) |
1504 | static 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 |
1534 | out: | 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 | ||
1543 | static 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 | ||
1564 | static size_t elf_core_vma_data_size(unsigned long mm_flags) | 1526 | static 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 | ||