diff options
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r-- | fs/binfmt_elf.c | 27 |
1 files changed, 16 insertions, 11 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; |