aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c127
1 files changed, 47 insertions, 80 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 4c94a79991bb..571a42326908 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -406,7 +406,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
406 goto out; 406 goto out;
407 if (!elf_check_arch(interp_elf_ex)) 407 if (!elf_check_arch(interp_elf_ex))
408 goto out; 408 goto out;
409 if (!interpreter->f_op || !interpreter->f_op->mmap) 409 if (!interpreter->f_op->mmap)
410 goto out; 410 goto out;
411 411
412 /* 412 /*
@@ -607,7 +607,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
607 goto out; 607 goto out;
608 if (!elf_check_arch(&loc->elf_ex)) 608 if (!elf_check_arch(&loc->elf_ex))
609 goto out; 609 goto out;
610 if (!bprm->file->f_op || !bprm->file->f_op->mmap) 610 if (!bprm->file->f_op->mmap)
611 goto out; 611 goto out;
612 612
613 /* Now read in all of the header information */ 613 /* Now read in all of the header information */
@@ -1028,7 +1028,7 @@ static int load_elf_library(struct file *file)
1028 1028
1029 /* First of all, some simple consistency checks */ 1029 /* First of all, some simple consistency checks */
1030 if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || 1030 if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
1031 !elf_check_arch(&elf_ex) || !file->f_op || !file->f_op->mmap) 1031 !elf_check_arch(&elf_ex) || !file->f_op->mmap)
1032 goto out; 1032 goto out;
1033 1033
1034 /* Now read in all of the header information */ 1034 /* Now read in all of the header information */
@@ -1225,35 +1225,17 @@ static int notesize(struct memelfnote *en)
1225 return sz; 1225 return sz;
1226} 1226}
1227 1227
1228#define DUMP_WRITE(addr, nr, foffset) \ 1228static int writenote(struct memelfnote *men, struct coredump_params *cprm)
1229 do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0)
1230
1231static int alignfile(struct file *file, loff_t *foffset)
1232{
1233 static const char buf[4] = { 0, };
1234 DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset);
1235 return 1;
1236}
1237
1238static int writenote(struct memelfnote *men, struct file *file,
1239 loff_t *foffset)
1240{ 1229{
1241 struct elf_note en; 1230 struct elf_note en;
1242 en.n_namesz = strlen(men->name) + 1; 1231 en.n_namesz = strlen(men->name) + 1;
1243 en.n_descsz = men->datasz; 1232 en.n_descsz = men->datasz;
1244 en.n_type = men->type; 1233 en.n_type = men->type;
1245 1234
1246 DUMP_WRITE(&en, sizeof(en), foffset); 1235 return dump_emit(cprm, &en, sizeof(en)) &&
1247 DUMP_WRITE(men->name, en.n_namesz, foffset); 1236 dump_emit(cprm, men->name, en.n_namesz) && dump_align(cprm, 4) &&
1248 if (!alignfile(file, foffset)) 1237 dump_emit(cprm, men->data, men->datasz) && dump_align(cprm, 4);
1249 return 0;
1250 DUMP_WRITE(men->data, men->datasz, foffset);
1251 if (!alignfile(file, foffset))
1252 return 0;
1253
1254 return 1;
1255} 1238}
1256#undef DUMP_WRITE
1257 1239
1258static void fill_elf_header(struct elfhdr *elf, int segs, 1240static void fill_elf_header(struct elfhdr *elf, int segs,
1259 u16 machine, u32 flags) 1241 u16 machine, u32 flags)
@@ -1392,7 +1374,7 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
1392} 1374}
1393 1375
1394static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata, 1376static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
1395 siginfo_t *siginfo) 1377 const siginfo_t *siginfo)
1396{ 1378{
1397 mm_segment_t old_fs = get_fs(); 1379 mm_segment_t old_fs = get_fs();
1398 set_fs(KERNEL_DS); 1380 set_fs(KERNEL_DS);
@@ -1599,7 +1581,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
1599 1581
1600static int fill_note_info(struct elfhdr *elf, int phdrs, 1582static int fill_note_info(struct elfhdr *elf, int phdrs,
1601 struct elf_note_info *info, 1583 struct elf_note_info *info,
1602 siginfo_t *siginfo, struct pt_regs *regs) 1584 const siginfo_t *siginfo, struct pt_regs *regs)
1603{ 1585{
1604 struct task_struct *dump_task = current; 1586 struct task_struct *dump_task = current;
1605 const struct user_regset_view *view = task_user_regset_view(dump_task); 1587 const struct user_regset_view *view = task_user_regset_view(dump_task);
@@ -1702,7 +1684,7 @@ static size_t get_note_info_size(struct elf_note_info *info)
1702 * process-wide notes are interleaved after the first thread-specific note. 1684 * process-wide notes are interleaved after the first thread-specific note.
1703 */ 1685 */
1704static int write_note_info(struct elf_note_info *info, 1686static int write_note_info(struct elf_note_info *info,
1705 struct file *file, loff_t *foffset) 1687 struct coredump_params *cprm)
1706{ 1688{
1707 bool first = 1; 1689 bool first = 1;
1708 struct elf_thread_core_info *t = info->thread; 1690 struct elf_thread_core_info *t = info->thread;
@@ -1710,22 +1692,22 @@ static int write_note_info(struct elf_note_info *info,
1710 do { 1692 do {
1711 int i; 1693 int i;
1712 1694
1713 if (!writenote(&t->notes[0], file, foffset)) 1695 if (!writenote(&t->notes[0], cprm))
1714 return 0; 1696 return 0;
1715 1697
1716 if (first && !writenote(&info->psinfo, file, foffset)) 1698 if (first && !writenote(&info->psinfo, cprm))
1717 return 0; 1699 return 0;
1718 if (first && !writenote(&info->signote, file, foffset)) 1700 if (first && !writenote(&info->signote, cprm))
1719 return 0; 1701 return 0;
1720 if (first && !writenote(&info->auxv, file, foffset)) 1702 if (first && !writenote(&info->auxv, cprm))
1721 return 0; 1703 return 0;
1722 if (first && info->files.data && 1704 if (first && info->files.data &&
1723 !writenote(&info->files, file, foffset)) 1705 !writenote(&info->files, cprm))
1724 return 0; 1706 return 0;
1725 1707
1726 for (i = 1; i < info->thread_notes; ++i) 1708 for (i = 1; i < info->thread_notes; ++i)
1727 if (t->notes[i].data && 1709 if (t->notes[i].data &&
1728 !writenote(&t->notes[i], file, foffset)) 1710 !writenote(&t->notes[i], cprm))
1729 return 0; 1711 return 0;
1730 1712
1731 first = 0; 1713 first = 0;
@@ -1848,34 +1830,31 @@ static int elf_note_info_init(struct elf_note_info *info)
1848 1830
1849static int fill_note_info(struct elfhdr *elf, int phdrs, 1831static int fill_note_info(struct elfhdr *elf, int phdrs,
1850 struct elf_note_info *info, 1832 struct elf_note_info *info,
1851 siginfo_t *siginfo, struct pt_regs *regs) 1833 const siginfo_t *siginfo, struct pt_regs *regs)
1852{ 1834{
1853 struct list_head *t; 1835 struct list_head *t;
1836 struct core_thread *ct;
1837 struct elf_thread_status *ets;
1854 1838
1855 if (!elf_note_info_init(info)) 1839 if (!elf_note_info_init(info))
1856 return 0; 1840 return 0;
1857 1841
1858 if (siginfo->si_signo) { 1842 for (ct = current->mm->core_state->dumper.next;
1859 struct core_thread *ct; 1843 ct; ct = ct->next) {
1860 struct elf_thread_status *ets; 1844 ets = kzalloc(sizeof(*ets), GFP_KERNEL);
1861 1845 if (!ets)
1862 for (ct = current->mm->core_state->dumper.next; 1846 return 0;
1863 ct; ct = ct->next) {
1864 ets = kzalloc(sizeof(*ets), GFP_KERNEL);
1865 if (!ets)
1866 return 0;
1867 1847
1868 ets->thread = ct->task; 1848 ets->thread = ct->task;
1869 list_add(&ets->list, &info->thread_list); 1849 list_add(&ets->list, &info->thread_list);
1870 } 1850 }
1871 1851
1872 list_for_each(t, &info->thread_list) { 1852 list_for_each(t, &info->thread_list) {
1873 int sz; 1853 int sz;
1874 1854
1875 ets = list_entry(t, struct elf_thread_status, list); 1855 ets = list_entry(t, struct elf_thread_status, list);
1876 sz = elf_dump_thread_status(siginfo->si_signo, ets); 1856 sz = elf_dump_thread_status(siginfo->si_signo, ets);
1877 info->thread_status_size += sz; 1857 info->thread_status_size += sz;
1878 }
1879 } 1858 }
1880 /* now collect the dump for the current */ 1859 /* now collect the dump for the current */
1881 memset(info->prstatus, 0, sizeof(*info->prstatus)); 1860 memset(info->prstatus, 0, sizeof(*info->prstatus));
@@ -1935,13 +1914,13 @@ static size_t get_note_info_size(struct elf_note_info *info)
1935} 1914}
1936 1915
1937static int write_note_info(struct elf_note_info *info, 1916static int write_note_info(struct elf_note_info *info,
1938 struct file *file, loff_t *foffset) 1917 struct coredump_params *cprm)
1939{ 1918{
1940 int i; 1919 int i;
1941 struct list_head *t; 1920 struct list_head *t;
1942 1921
1943 for (i = 0; i < info->numnote; i++) 1922 for (i = 0; i < info->numnote; i++)
1944 if (!writenote(info->notes + i, file, foffset)) 1923 if (!writenote(info->notes + i, cprm))
1945 return 0; 1924 return 0;
1946 1925
1947 /* write out the thread status notes section */ 1926 /* write out the thread status notes section */
@@ -1950,7 +1929,7 @@ static int write_note_info(struct elf_note_info *info,
1950 list_entry(t, struct elf_thread_status, list); 1929 list_entry(t, struct elf_thread_status, list);
1951 1930
1952 for (i = 0; i < tmp->num_notes; i++) 1931 for (i = 0; i < tmp->num_notes; i++)
1953 if (!writenote(&tmp->notes[i], file, foffset)) 1932 if (!writenote(&tmp->notes[i], cprm))
1954 return 0; 1933 return 0;
1955 } 1934 }
1956 1935
@@ -2046,10 +2025,9 @@ static int elf_core_dump(struct coredump_params *cprm)
2046 int has_dumped = 0; 2025 int has_dumped = 0;
2047 mm_segment_t fs; 2026 mm_segment_t fs;
2048 int segs; 2027 int segs;
2049 size_t size = 0;
2050 struct vm_area_struct *vma, *gate_vma; 2028 struct vm_area_struct *vma, *gate_vma;
2051 struct elfhdr *elf = NULL; 2029 struct elfhdr *elf = NULL;
2052 loff_t offset = 0, dataoff, foffset; 2030 loff_t offset = 0, dataoff;
2053 struct elf_note_info info = { }; 2031 struct elf_note_info info = { };
2054 struct elf_phdr *phdr4note = NULL; 2032 struct elf_phdr *phdr4note = NULL;
2055 struct elf_shdr *shdr4extnum = NULL; 2033 struct elf_shdr *shdr4extnum = NULL;
@@ -2105,7 +2083,6 @@ static int elf_core_dump(struct coredump_params *cprm)
2105 2083
2106 offset += sizeof(*elf); /* Elf header */ 2084 offset += sizeof(*elf); /* Elf header */
2107 offset += segs * sizeof(struct elf_phdr); /* Program headers */ 2085 offset += segs * sizeof(struct elf_phdr); /* Program headers */
2108 foffset = offset;
2109 2086
2110 /* Write notes phdr entry */ 2087 /* Write notes phdr entry */
2111 { 2088 {
@@ -2136,13 +2113,10 @@ static int elf_core_dump(struct coredump_params *cprm)
2136 2113
2137 offset = dataoff; 2114 offset = dataoff;
2138 2115
2139 size += sizeof(*elf); 2116 if (!dump_emit(cprm, elf, sizeof(*elf)))
2140 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
2141 goto end_coredump; 2117 goto end_coredump;
2142 2118
2143 size += sizeof(*phdr4note); 2119 if (!dump_emit(cprm, phdr4note, sizeof(*phdr4note)))
2144 if (size > cprm->limit
2145 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
2146 goto end_coredump; 2120 goto end_coredump;
2147 2121
2148 /* Write program headers for segments dump */ 2122 /* Write program headers for segments dump */
@@ -2164,24 +2138,22 @@ static int elf_core_dump(struct coredump_params *cprm)
2164 phdr.p_flags |= PF_X; 2138 phdr.p_flags |= PF_X;
2165 phdr.p_align = ELF_EXEC_PAGESIZE; 2139 phdr.p_align = ELF_EXEC_PAGESIZE;
2166 2140
2167 size += sizeof(phdr); 2141 if (!dump_emit(cprm, &phdr, sizeof(phdr)))
2168 if (size > cprm->limit
2169 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
2170 goto end_coredump; 2142 goto end_coredump;
2171 } 2143 }
2172 2144
2173 if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit)) 2145 if (!elf_core_write_extra_phdrs(cprm, offset))
2174 goto end_coredump; 2146 goto end_coredump;
2175 2147
2176 /* write out the notes section */ 2148 /* write out the notes section */
2177 if (!write_note_info(&info, cprm->file, &foffset)) 2149 if (!write_note_info(&info, cprm))
2178 goto end_coredump; 2150 goto end_coredump;
2179 2151
2180 if (elf_coredump_extra_notes_write(cprm->file, &foffset)) 2152 if (elf_coredump_extra_notes_write(cprm))
2181 goto end_coredump; 2153 goto end_coredump;
2182 2154
2183 /* Align to page */ 2155 /* Align to page */
2184 if (!dump_seek(cprm->file, dataoff - foffset)) 2156 if (!dump_skip(cprm, dataoff - cprm->written))
2185 goto end_coredump; 2157 goto end_coredump;
2186 2158
2187 for (vma = first_vma(current, gate_vma); vma != NULL; 2159 for (vma = first_vma(current, gate_vma); vma != NULL;
@@ -2198,26 +2170,21 @@ static int elf_core_dump(struct coredump_params *cprm)
2198 page = get_dump_page(addr); 2170 page = get_dump_page(addr);
2199 if (page) { 2171 if (page) {
2200 void *kaddr = kmap(page); 2172 void *kaddr = kmap(page);
2201 stop = ((size += PAGE_SIZE) > cprm->limit) || 2173 stop = !dump_emit(cprm, kaddr, PAGE_SIZE);
2202 !dump_write(cprm->file, kaddr,
2203 PAGE_SIZE);
2204 kunmap(page); 2174 kunmap(page);
2205 page_cache_release(page); 2175 page_cache_release(page);
2206 } else 2176 } else
2207 stop = !dump_seek(cprm->file, PAGE_SIZE); 2177 stop = !dump_skip(cprm, PAGE_SIZE);
2208 if (stop) 2178 if (stop)
2209 goto end_coredump; 2179 goto end_coredump;
2210 } 2180 }
2211 } 2181 }
2212 2182
2213 if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit)) 2183 if (!elf_core_write_extra_data(cprm))
2214 goto end_coredump; 2184 goto end_coredump;
2215 2185
2216 if (e_phnum == PN_XNUM) { 2186 if (e_phnum == PN_XNUM) {
2217 size += sizeof(*shdr4extnum); 2187 if (!dump_emit(cprm, shdr4extnum, sizeof(*shdr4extnum)))
2218 if (size > cprm->limit
2219 || !dump_write(cprm->file, shdr4extnum,
2220 sizeof(*shdr4extnum)))
2221 goto end_coredump; 2188 goto end_coredump;
2222 } 2189 }
2223 2190