aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-05 15:32:35 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-11-09 00:16:22 -0500
commitecc8c7725e6c21528329b34acae2a1d64b3af89b (patch)
treeae1790c2ce0fe1c1f02e2bd0795b6636d65b4587 /fs/binfmt_elf.c
parent7d2f551f6dc933f87933e906e48583169bbc7c27 (diff)
new helper: dump_emit()
dump_write() analog, takes core_dump_params instead of file, keeps track of the amount written in cprm->written and checks for cprm->limit. Start using it in binfmt_elf.c... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c60
1 files changed, 23 insertions, 37 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 501c8a4d6eb1..00fd9c969a27 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1225,35 +1225,23 @@ 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 alignfile(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{ 1229{
1233 static const char buf[4] = { 0, }; 1230 static const char buf[4] = { 0, };
1234 DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset); 1231 return dump_emit(cprm, buf, roundup(cprm->written, 4) - cprm->written);
1235 return 1;
1236} 1232}
1237 1233
1238static int writenote(struct memelfnote *men, struct file *file, 1234static int writenote(struct memelfnote *men, struct coredump_params *cprm)
1239 loff_t *foffset)
1240{ 1235{
1241 struct elf_note en; 1236 struct elf_note en;
1242 en.n_namesz = strlen(men->name) + 1; 1237 en.n_namesz = strlen(men->name) + 1;
1243 en.n_descsz = men->datasz; 1238 en.n_descsz = men->datasz;
1244 en.n_type = men->type; 1239 en.n_type = men->type;
1245 1240
1246 DUMP_WRITE(&en, sizeof(en), foffset); 1241 return dump_emit(cprm, &en, sizeof(en)) &&
1247 DUMP_WRITE(men->name, en.n_namesz, foffset); 1242 dump_emit(cprm, men->name, en.n_namesz) && alignfile(cprm) &&
1248 if (!alignfile(file, foffset)) 1243 dump_emit(cprm, men->data, men->datasz) && alignfile(cprm);
1249 return 0;
1250 DUMP_WRITE(men->data, men->datasz, foffset);
1251 if (!alignfile(file, foffset))
1252 return 0;
1253
1254 return 1;
1255} 1244}
1256#undef DUMP_WRITE
1257 1245
1258static void fill_elf_header(struct elfhdr *elf, int segs, 1246static void fill_elf_header(struct elfhdr *elf, int segs,
1259 u16 machine, u32 flags) 1247 u16 machine, u32 flags)
@@ -1702,7 +1690,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. 1690 * process-wide notes are interleaved after the first thread-specific note.
1703 */ 1691 */
1704static int write_note_info(struct elf_note_info *info, 1692static int write_note_info(struct elf_note_info *info,
1705 struct file *file, loff_t *foffset) 1693 struct coredump_params *cprm)
1706{ 1694{
1707 bool first = 1; 1695 bool first = 1;
1708 struct elf_thread_core_info *t = info->thread; 1696 struct elf_thread_core_info *t = info->thread;
@@ -1710,22 +1698,22 @@ static int write_note_info(struct elf_note_info *info,
1710 do { 1698 do {
1711 int i; 1699 int i;
1712 1700
1713 if (!writenote(&t->notes[0], file, foffset)) 1701 if (!writenote(&t->notes[0], cprm))
1714 return 0; 1702 return 0;
1715 1703
1716 if (first && !writenote(&info->psinfo, file, foffset)) 1704 if (first && !writenote(&info->psinfo, cprm))
1717 return 0; 1705 return 0;
1718 if (first && !writenote(&info->signote, file, foffset)) 1706 if (first && !writenote(&info->signote, cprm))
1719 return 0; 1707 return 0;
1720 if (first && !writenote(&info->auxv, file, foffset)) 1708 if (first && !writenote(&info->auxv, cprm))
1721 return 0; 1709 return 0;
1722 if (first && info->files.data && 1710 if (first && info->files.data &&
1723 !writenote(&info->files, file, foffset)) 1711 !writenote(&info->files, cprm))
1724 return 0; 1712 return 0;
1725 1713
1726 for (i = 1; i < info->thread_notes; ++i) 1714 for (i = 1; i < info->thread_notes; ++i)
1727 if (t->notes[i].data && 1715 if (t->notes[i].data &&
1728 !writenote(&t->notes[i], file, foffset)) 1716 !writenote(&t->notes[i], cprm))
1729 return 0; 1717 return 0;
1730 1718
1731 first = 0; 1719 first = 0;
@@ -1935,13 +1923,13 @@ static size_t get_note_info_size(struct elf_note_info *info)
1935} 1923}
1936 1924
1937static int write_note_info(struct elf_note_info *info, 1925static int write_note_info(struct elf_note_info *info,
1938 struct file *file, loff_t *foffset) 1926 struct coredump_params *cprm)
1939{ 1927{
1940 int i; 1928 int i;
1941 struct list_head *t; 1929 struct list_head *t;
1942 1930
1943 for (i = 0; i < info->numnote; i++) 1931 for (i = 0; i < info->numnote; i++)
1944 if (!writenote(info->notes + i, file, foffset)) 1932 if (!writenote(info->notes + i, cprm))
1945 return 0; 1933 return 0;
1946 1934
1947 /* write out the thread status notes section */ 1935 /* write out the thread status notes section */
@@ -1950,7 +1938,7 @@ static int write_note_info(struct elf_note_info *info,
1950 list_entry(t, struct elf_thread_status, list); 1938 list_entry(t, struct elf_thread_status, list);
1951 1939
1952 for (i = 0; i < tmp->num_notes; i++) 1940 for (i = 0; i < tmp->num_notes; i++)
1953 if (!writenote(&tmp->notes[i], file, foffset)) 1941 if (!writenote(&tmp->notes[i], cprm))
1954 return 0; 1942 return 0;
1955 } 1943 }
1956 1944
@@ -2136,13 +2124,10 @@ static int elf_core_dump(struct coredump_params *cprm)
2136 2124
2137 offset = dataoff; 2125 offset = dataoff;
2138 2126
2139 size += sizeof(*elf); 2127 if (!dump_emit(cprm, elf, sizeof(*elf)))
2140 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
2141 goto end_coredump; 2128 goto end_coredump;
2142 2129
2143 size += sizeof(*phdr4note); 2130 if (!dump_emit(cprm, phdr4note, sizeof(*phdr4note)))
2144 if (size > cprm->limit
2145 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
2146 goto end_coredump; 2131 goto end_coredump;
2147 2132
2148 /* Write program headers for segments dump */ 2133 /* Write program headers for segments dump */
@@ -2164,19 +2149,20 @@ static int elf_core_dump(struct coredump_params *cprm)
2164 phdr.p_flags |= PF_X; 2149 phdr.p_flags |= PF_X;
2165 phdr.p_align = ELF_EXEC_PAGESIZE; 2150 phdr.p_align = ELF_EXEC_PAGESIZE;
2166 2151
2167 size += sizeof(phdr); 2152 if (!dump_emit(cprm, &phdr, sizeof(phdr)))
2168 if (size > cprm->limit
2169 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
2170 goto end_coredump; 2153 goto end_coredump;
2171 } 2154 }
2155 size = cprm->written;
2172 2156
2173 if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit)) 2157 if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
2174 goto end_coredump; 2158 goto end_coredump;
2175 2159
2160 cprm->written = foffset; /* will disappear */
2176 /* write out the notes section */ 2161 /* write out the notes section */
2177 if (!write_note_info(&info, cprm->file, &foffset)) 2162 if (!write_note_info(&info, cprm))
2178 goto end_coredump; 2163 goto end_coredump;
2179 2164
2165 foffset = cprm->written;
2180 if (elf_coredump_extra_notes_write(cprm->file, &foffset)) 2166 if (elf_coredump_extra_notes_write(cprm->file, &foffset))
2181 goto end_coredump; 2167 goto end_coredump;
2182 2168