summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Schnelle <svens@stackframe.org>2019-08-23 15:49:15 -0400
committerHelge Deller <deller@gmx.de>2019-09-06 17:58:43 -0400
commit5f71d977206f3b2990ba304766ddaa9e81dbe700 (patch)
treefa39f353744ce3736b9fca68ff24719555d8bd1e
parentd34e0ad3eaf45c612cc7b5baa0f6b2f2a6d75612 (diff)
kexec_elf: remove parsing of section headers
We're not using them, so we can drop the parsing. Signed-off-by: Sven Schnelle <svens@stackframe.org> Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com> Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--include/linux/kexec.h1
-rw-r--r--kernel/kexec_elf.c137
2 files changed, 0 insertions, 138 deletions
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index da2a6b1d69e7..f0b809258ed3 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -226,7 +226,6 @@ struct kexec_elf_info {
226 226
227 const struct elfhdr *ehdr; 227 const struct elfhdr *ehdr;
228 const struct elf_phdr *proghdrs; 228 const struct elf_phdr *proghdrs;
229 struct elf_shdr *sechdrs;
230}; 229};
231 230
232int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr, 231int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr,
diff --git a/kernel/kexec_elf.c b/kernel/kexec_elf.c
index 34376fbc55be..137037603117 100644
--- a/kernel/kexec_elf.c
+++ b/kernel/kexec_elf.c
@@ -258,134 +258,6 @@ static int elf_read_phdrs(const char *buf, size_t len,
258} 258}
259 259
260/** 260/**
261 * elf_is_shdr_sane - check that it is safe to use the section header
262 * @buf_len: size of the buffer in which the ELF file is loaded.
263 */
264static bool elf_is_shdr_sane(const struct elf_shdr *shdr, size_t buf_len)
265{
266 bool size_ok;
267
268 /* SHT_NULL headers have undefined values, so we can't check them. */
269 if (shdr->sh_type == SHT_NULL)
270 return true;
271
272 /* Now verify sh_entsize */
273 switch (shdr->sh_type) {
274 case SHT_SYMTAB:
275 size_ok = shdr->sh_entsize == sizeof(Elf_Sym);
276 break;
277 case SHT_RELA:
278 size_ok = shdr->sh_entsize == sizeof(Elf_Rela);
279 break;
280 case SHT_DYNAMIC:
281 size_ok = shdr->sh_entsize == sizeof(Elf_Dyn);
282 break;
283 case SHT_REL:
284 size_ok = shdr->sh_entsize == sizeof(Elf_Rel);
285 break;
286 case SHT_NOTE:
287 case SHT_PROGBITS:
288 case SHT_HASH:
289 case SHT_NOBITS:
290 default:
291 /*
292 * This is a section whose entsize requirements
293 * I don't care about. If I don't know about
294 * the section I can't care about it's entsize
295 * requirements.
296 */
297 size_ok = true;
298 break;
299 }
300
301 if (!size_ok) {
302 pr_debug("ELF section with wrong entry size.\n");
303 return false;
304 } else if (shdr->sh_addr + shdr->sh_size < shdr->sh_addr) {
305 pr_debug("ELF section address wraps around.\n");
306 return false;
307 }
308
309 if (shdr->sh_type != SHT_NOBITS) {
310 if (shdr->sh_offset + shdr->sh_size < shdr->sh_offset) {
311 pr_debug("ELF section location wraps around.\n");
312 return false;
313 } else if (shdr->sh_offset + shdr->sh_size > buf_len) {
314 pr_debug("ELF section not in file.\n");
315 return false;
316 }
317 }
318
319 return true;
320}
321
322static int elf_read_shdr(const char *buf, size_t len,
323 struct kexec_elf_info *elf_info,
324 int idx)
325{
326 struct elf_shdr *shdr = &elf_info->sechdrs[idx];
327 const struct elfhdr *ehdr = elf_info->ehdr;
328 const char *sbuf;
329 struct elf_shdr *buf_shdr;
330
331 sbuf = buf + ehdr->e_shoff + idx * sizeof(*buf_shdr);
332 buf_shdr = (struct elf_shdr *) sbuf;
333
334 shdr->sh_name = elf32_to_cpu(ehdr, buf_shdr->sh_name);
335 shdr->sh_type = elf32_to_cpu(ehdr, buf_shdr->sh_type);
336 shdr->sh_addr = elf_addr_to_cpu(ehdr, buf_shdr->sh_addr);
337 shdr->sh_offset = elf_addr_to_cpu(ehdr, buf_shdr->sh_offset);
338 shdr->sh_link = elf32_to_cpu(ehdr, buf_shdr->sh_link);
339 shdr->sh_info = elf32_to_cpu(ehdr, buf_shdr->sh_info);
340
341 /*
342 * The following fields have a type equivalent to Elf_Addr
343 * both in 32 bit and 64 bit ELF.
344 */
345 shdr->sh_flags = elf_addr_to_cpu(ehdr, buf_shdr->sh_flags);
346 shdr->sh_size = elf_addr_to_cpu(ehdr, buf_shdr->sh_size);
347 shdr->sh_addralign = elf_addr_to_cpu(ehdr, buf_shdr->sh_addralign);
348 shdr->sh_entsize = elf_addr_to_cpu(ehdr, buf_shdr->sh_entsize);
349
350 return elf_is_shdr_sane(shdr, len) ? 0 : -ENOEXEC;
351}
352
353/**
354 * elf_read_shdrs - read the section headers from the buffer
355 *
356 * This function assumes that the section header table was checked for sanity.
357 * Use elf_is_ehdr_sane() if it wasn't.
358 */
359static int elf_read_shdrs(const char *buf, size_t len,
360 struct kexec_elf_info *elf_info)
361{
362 size_t shdr_size, i;
363
364 /*
365 * e_shnum is at most 65536 so calculating
366 * the size of the section header cannot overflow.
367 */
368 shdr_size = sizeof(struct elf_shdr) * elf_info->ehdr->e_shnum;
369
370 elf_info->sechdrs = kzalloc(shdr_size, GFP_KERNEL);
371 if (!elf_info->sechdrs)
372 return -ENOMEM;
373
374 for (i = 0; i < elf_info->ehdr->e_shnum; i++) {
375 int ret;
376
377 ret = elf_read_shdr(buf, len, elf_info, i);
378 if (ret) {
379 kfree(elf_info->sechdrs);
380 elf_info->sechdrs = NULL;
381 return ret;
382 }
383 }
384
385 return 0;
386}
387
388/**
389 * elf_read_from_buffer - read ELF file and sets up ELF header and ELF info 261 * elf_read_from_buffer - read ELF file and sets up ELF header and ELF info
390 * @buf: Buffer to read ELF file from. 262 * @buf: Buffer to read ELF file from.
391 * @len: Size of @buf. 263 * @len: Size of @buf.
@@ -417,14 +289,6 @@ static int elf_read_from_buffer(const char *buf, size_t len,
417 if (ret) 289 if (ret)
418 return ret; 290 return ret;
419 } 291 }
420 if (ehdr->e_shoff > 0 && ehdr->e_shnum > 0) {
421 ret = elf_read_shdrs(buf, len, elf_info);
422 if (ret) {
423 kfree(elf_info->proghdrs);
424 return ret;
425 }
426 }
427
428 return 0; 292 return 0;
429} 293}
430 294
@@ -434,7 +298,6 @@ static int elf_read_from_buffer(const char *buf, size_t len,
434void kexec_free_elf_info(struct kexec_elf_info *elf_info) 298void kexec_free_elf_info(struct kexec_elf_info *elf_info)
435{ 299{
436 kfree(elf_info->proghdrs); 300 kfree(elf_info->proghdrs);
437 kfree(elf_info->sechdrs);
438 memset(elf_info, 0, sizeof(*elf_info)); 301 memset(elf_info, 0, sizeof(*elf_info));
439} 302}
440/** 303/**