diff options
author | Sven Schnelle <svens@stackframe.org> | 2019-08-23 15:49:15 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2019-09-06 17:58:43 -0400 |
commit | 5f71d977206f3b2990ba304766ddaa9e81dbe700 (patch) | |
tree | fa39f353744ce3736b9fca68ff24719555d8bd1e | |
parent | d34e0ad3eaf45c612cc7b5baa0f6b2f2a6d75612 (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.h | 1 | ||||
-rw-r--r-- | kernel/kexec_elf.c | 137 |
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 | ||
232 | int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr, | 231 | int 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 | */ | ||
264 | static 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 | |||
322 | static 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 | */ | ||
359 | static 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, | |||
434 | void kexec_free_elf_info(struct kexec_elf_info *elf_info) | 298 | void 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 | /** |