diff options
-rw-r--r-- | fs/binfmt_elf.c | 27 | ||||
-rw-r--r-- | fs/binfmt_elf_fdpic.c | 29 |
2 files changed, 32 insertions, 24 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index c1a499599b7d..6fc49b6ed936 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1856,6 +1856,7 @@ static int elf_core_dump(struct coredump_params *cprm) | |||
1856 | loff_t offset = 0, dataoff, foffset; | 1856 | loff_t offset = 0, dataoff, foffset; |
1857 | unsigned long mm_flags; | 1857 | unsigned long mm_flags; |
1858 | struct elf_note_info info; | 1858 | struct elf_note_info info; |
1859 | struct elf_phdr *phdr4note = NULL; | ||
1859 | 1860 | ||
1860 | /* | 1861 | /* |
1861 | * We no longer stop all VM operations. | 1862 | * We no longer stop all VM operations. |
@@ -1898,28 +1899,22 @@ static int elf_core_dump(struct coredump_params *cprm) | |||
1898 | fs = get_fs(); | 1899 | fs = get_fs(); |
1899 | set_fs(KERNEL_DS); | 1900 | set_fs(KERNEL_DS); |
1900 | 1901 | ||
1901 | size += sizeof(*elf); | ||
1902 | if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf))) | ||
1903 | goto end_coredump; | ||
1904 | |||
1905 | offset += sizeof(*elf); /* Elf header */ | 1902 | offset += sizeof(*elf); /* Elf header */ |
1906 | offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */ | 1903 | offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */ |
1907 | foffset = offset; | 1904 | foffset = offset; |
1908 | 1905 | ||
1909 | /* Write notes phdr entry */ | 1906 | /* Write notes phdr entry */ |
1910 | { | 1907 | { |
1911 | struct elf_phdr phdr; | ||
1912 | size_t sz = get_note_info_size(&info); | 1908 | size_t sz = get_note_info_size(&info); |
1913 | 1909 | ||
1914 | sz += elf_coredump_extra_notes_size(); | 1910 | sz += elf_coredump_extra_notes_size(); |
1915 | 1911 | ||
1916 | fill_elf_note_phdr(&phdr, sz, offset); | 1912 | phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL); |
1917 | offset += sz; | 1913 | if (!phdr4note) |
1918 | |||
1919 | size += sizeof(phdr); | ||
1920 | if (size > cprm->limit | ||
1921 | || !dump_write(cprm->file, &phdr, sizeof(phdr))) | ||
1922 | goto end_coredump; | 1914 | goto end_coredump; |
1915 | |||
1916 | fill_elf_note_phdr(phdr4note, sz, offset); | ||
1917 | offset += sz; | ||
1923 | } | 1918 | } |
1924 | 1919 | ||
1925 | dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); | 1920 | dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); |
@@ -1931,6 +1926,15 @@ static int elf_core_dump(struct coredump_params *cprm) | |||
1931 | */ | 1926 | */ |
1932 | mm_flags = current->mm->flags; | 1927 | mm_flags = current->mm->flags; |
1933 | 1928 | ||
1929 | size += sizeof(*elf); | ||
1930 | if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf))) | ||
1931 | goto end_coredump; | ||
1932 | |||
1933 | size += sizeof(*phdr4note); | ||
1934 | if (size > cprm->limit | ||
1935 | || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note))) | ||
1936 | goto end_coredump; | ||
1937 | |||
1934 | /* Write program headers for segments dump */ | 1938 | /* Write program headers for segments dump */ |
1935 | for (vma = first_vma(current, gate_vma); vma != NULL; | 1939 | for (vma = first_vma(current, gate_vma); vma != NULL; |
1936 | vma = next_vma(vma, gate_vma)) { | 1940 | vma = next_vma(vma, gate_vma)) { |
@@ -2004,6 +2008,7 @@ end_coredump: | |||
2004 | 2008 | ||
2005 | cleanup: | 2009 | cleanup: |
2006 | free_note_info(&info); | 2010 | free_note_info(&info); |
2011 | kfree(phdr4note); | ||
2007 | kfree(elf); | 2012 | kfree(elf); |
2008 | out: | 2013 | out: |
2009 | return has_dumped; | 2014 | return has_dumped; |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 952699a86ec3..112da491d75d 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1600,6 +1600,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) | |||
1600 | int thread_status_size = 0; | 1600 | int thread_status_size = 0; |
1601 | elf_addr_t *auxv; | 1601 | elf_addr_t *auxv; |
1602 | unsigned long mm_flags; | 1602 | unsigned long mm_flags; |
1603 | struct elf_phdr *phdr4note = NULL; | ||
1603 | 1604 | ||
1604 | /* | 1605 | /* |
1605 | * We no longer stop all VM operations. | 1606 | * We no longer stop all VM operations. |
@@ -1706,18 +1707,12 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) | |||
1706 | fs = get_fs(); | 1707 | fs = get_fs(); |
1707 | set_fs(KERNEL_DS); | 1708 | set_fs(KERNEL_DS); |
1708 | 1709 | ||
1709 | size += sizeof(*elf); | ||
1710 | if (size > cprm->limit | ||
1711 | || !dump_write(cprm->file, elf, sizeof(*elf))) | ||
1712 | goto end_coredump; | ||
1713 | |||
1714 | offset += sizeof(*elf); /* Elf header */ | 1710 | offset += sizeof(*elf); /* Elf header */ |
1715 | offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */ | 1711 | offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */ |
1716 | foffset = offset; | 1712 | foffset = offset; |
1717 | 1713 | ||
1718 | /* Write notes phdr entry */ | 1714 | /* Write notes phdr entry */ |
1719 | { | 1715 | { |
1720 | struct elf_phdr phdr; | ||
1721 | int sz = 0; | 1716 | int sz = 0; |
1722 | 1717 | ||
1723 | for (i = 0; i < numnote; i++) | 1718 | for (i = 0; i < numnote; i++) |
@@ -1725,13 +1720,12 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) | |||
1725 | 1720 | ||
1726 | sz += thread_status_size; | 1721 | sz += thread_status_size; |
1727 | 1722 | ||
1728 | fill_elf_note_phdr(&phdr, sz, offset); | 1723 | phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL); |
1729 | offset += sz; | 1724 | if (!phdr4note) |
1730 | |||
1731 | size += sizeof(phdr); | ||
1732 | if (size > cprm->limit | ||
1733 | || !dump_write(cprm->file, &phdr, sizeof(phdr))) | ||
1734 | goto end_coredump; | 1725 | goto end_coredump; |
1726 | |||
1727 | fill_elf_note_phdr(phdr4note, sz, offset); | ||
1728 | offset += sz; | ||
1735 | } | 1729 | } |
1736 | 1730 | ||
1737 | /* Page-align dumped data */ | 1731 | /* Page-align dumped data */ |
@@ -1744,6 +1738,15 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) | |||
1744 | */ | 1738 | */ |
1745 | mm_flags = current->mm->flags; | 1739 | mm_flags = current->mm->flags; |
1746 | 1740 | ||
1741 | size += sizeof(*elf); | ||
1742 | if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf))) | ||
1743 | goto end_coredump; | ||
1744 | |||
1745 | size += sizeof(*phdr4note); | ||
1746 | if (size > cprm->limit | ||
1747 | || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note))) | ||
1748 | goto end_coredump; | ||
1749 | |||
1747 | /* write program headers for segments dump */ | 1750 | /* write program headers for segments dump */ |
1748 | for (vma = current->mm->mmap; vma; vma = vma->vm_next) { | 1751 | for (vma = current->mm->mmap; vma; vma = vma->vm_next) { |
1749 | struct elf_phdr phdr; | 1752 | struct elf_phdr phdr; |
@@ -1815,7 +1818,7 @@ cleanup: | |||
1815 | list_del(tmp); | 1818 | list_del(tmp); |
1816 | kfree(list_entry(tmp, struct elf_thread_status, list)); | 1819 | kfree(list_entry(tmp, struct elf_thread_status, list)); |
1817 | } | 1820 | } |
1818 | 1821 | kfree(phdr4note); | |
1819 | kfree(elf); | 1822 | kfree(elf); |
1820 | kfree(prstatus); | 1823 | kfree(prstatus); |
1821 | kfree(psinfo); | 1824 | kfree(psinfo); |