From: Mark Wielaard Date: Wed, 7 Oct 2015 22:16:03 +0000 (+0200) Subject: Allocate exact amount of bytes for phdrs and shdrs. X-Git-Tag: elfutils-0.164~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=86ed7f7f53179d7a893329e6b9851dbb75aba405;p=thirdparty%2Felfutils.git Allocate exact amount of bytes for phdrs and shdrs. Signed-off-by: Mark Wielaard --- diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 949a3728e..ee41405e8 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,13 @@ +2015-10-07 Mark Wielaard + + * dwfl_module_getdwarf.c (MAX): Removed. + (find_prelink_address_sync): Allocate exact amount of bytes for + phdrs and shdrs. + * dwfl_segment_report_module.c (dwfl_segment_report_module): + Likewise for phdrs. + * elf-from-memory.c (MAX): Removed. + (elf_from_remote_memory): Allocate exact amount of bytes for phdrs. + 2015-10-05 Chih-Hung Hsieh * dwfl_module_getdwarf.c (find_prelink_address_sync): Do not use diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c index c339040e4..a35905775 100644 --- a/libdwfl/dwfl_module_getdwarf.c +++ b/libdwfl/dwfl_module_getdwarf.c @@ -34,10 +34,6 @@ #include "../libdw/libdwP.h" /* DWARF_E_* values are here. */ #include "../libelf/libelfP.h" -#ifndef MAX -# define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - static inline Dwfl_Error open_elf_file (Elf **elf, int *fd, char **name) { @@ -371,15 +367,13 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file) src.d_size = phnum * phentsize; GElf_Addr undo_interp = 0; + bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32; { - if (unlikely (phnum > - SIZE_MAX / MAX (sizeof (Elf32_Phdr), sizeof (Elf64_Phdr)))) + size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr); + if (unlikely (phnum > SIZE_MAX / phdr_size)) return DWFL_E_NOMEM; - const size_t phdrs_bytes = - phnum * MAX (sizeof (Elf32_Phdr), sizeof (Elf64_Phdr)); + const size_t phdrs_bytes = phnum * phdr_size; void *phdrs = malloc (phdrs_bytes); - Elf32_Phdr (*p32)[phnum] = phdrs; - Elf64_Phdr (*p64)[phnum] = phdrs; if (unlikely (phdrs == NULL)) return DWFL_E_NOMEM; dst.d_buf = phdrs; @@ -390,8 +384,9 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file) free (phdrs); return DWFL_E_LIBELF; } - if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) + if (class32) { + Elf32_Phdr (*p32)[phnum] = phdrs; for (uint_fast16_t i = 0; i < phnum; ++i) if ((*p32)[i].p_type == PT_INTERP) { @@ -401,6 +396,7 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file) } else { + Elf64_Phdr (*p64)[phnum] = phdrs; for (uint_fast16_t i = 0; i < phnum; ++i) if ((*p64)[i].p_type == PT_INTERP) { @@ -418,14 +414,11 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file) src.d_type = ELF_T_SHDR; src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum - 1, EV_CURRENT); - if (unlikely (shnum - 1 > - SIZE_MAX / MAX (sizeof (Elf32_Shdr), sizeof (Elf64_Shdr)))) + size_t shdr_size = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr); + if (unlikely (shnum - 1 > SIZE_MAX / shdr_size)) return DWFL_E_NOMEM; - const size_t shdrs_bytes = - (shnum - 1) * MAX (sizeof (Elf32_Shdr), sizeof (Elf64_Shdr)); + const size_t shdrs_bytes = (shnum - 1) * shdr_size; void *shdrs = malloc (shdrs_bytes); - Elf32_Shdr (*s32)[shnum - 1] = shdrs; - Elf64_Shdr (*s64)[shnum - 1] = shdrs; if (unlikely (shdrs == NULL)) return DWFL_E_NOMEM; dst.d_buf = shdrs; @@ -490,16 +483,22 @@ find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file) mod->main.address_sync = highest; highest = 0; - if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) - for (size_t i = 0; i < shnum - 1; ++i) - consider_shdr (undo_interp, (*s32)[i].sh_type, - (*s32)[i].sh_flags, (*s32)[i].sh_addr, - (*s32)[i].sh_size); + if (class32) + { + Elf32_Shdr (*s32)[shnum - 1] = shdrs; + for (size_t i = 0; i < shnum - 1; ++i) + consider_shdr (undo_interp, (*s32)[i].sh_type, + (*s32)[i].sh_flags, (*s32)[i].sh_addr, + (*s32)[i].sh_size); + } else - for (size_t i = 0; i < shnum - 1; ++i) - consider_shdr (undo_interp, (*s64)[i].sh_type, - (*s64)[i].sh_flags, (*s64)[i].sh_addr, - (*s64)[i].sh_size); + { + Elf64_Shdr (*s64)[shnum - 1] = shdrs; + for (size_t i = 0; i < shnum - 1; ++i) + consider_shdr (undo_interp, (*s64)[i].sh_type, + (*s64)[i].sh_flags, (*s64)[i].sh_addr, + (*s64)[i].sh_size); + } if (highest > file->vaddr) file->address_sync = highest; diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 92f691d83..ca86c3115 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -408,14 +408,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, xlatefrom.d_buf = ph_buffer; - if (unlikely (phnum > - SIZE_MAX / MAX (sizeof (Elf32_Phdr), sizeof (Elf64_Phdr)))) + bool class32 = ei_class == ELFCLASS32; + size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr); + if (unlikely (phnum > SIZE_MAX / phdr_size)) return finish (); - const size_t phdrsp_bytes = - phnum * MAX (sizeof (Elf32_Phdr), sizeof (Elf64_Phdr)); + const size_t phdrsp_bytes = phnum * phdr_size; phdrsp = malloc (phdrsp_bytes); - Elf32_Phdr (*p32)[phnum] = phdrsp; - Elf64_Phdr (*p64)[phnum] = phdrsp; if (unlikely (phdrsp == NULL)) return finish (); @@ -577,6 +575,9 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, break; } } + + Elf32_Phdr (*p32)[phnum] = phdrsp; + Elf64_Phdr (*p64)[phnum] = phdrsp; if (ei_class == ELFCLASS32) { if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL) diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c index 5be21bb03..dd42e9540 100644 --- a/libdwfl/elf-from-memory.c +++ b/libdwfl/elf-from-memory.c @@ -38,10 +38,6 @@ #include #include -#ifndef MAX -# define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - /* Reconstruct an ELF file by reading the segments out of remote memory based on the ELF file header at EHDR_VMA and the ELF program headers it points to. If not null, *LOADBASEP is filled in with the difference @@ -195,17 +191,15 @@ elf_from_remote_memory (GElf_Addr ehdr_vma, xlatefrom.d_buf = buffer; } - if (unlikely (phnum > - SIZE_MAX / MAX (sizeof (Elf32_Phdr), sizeof (Elf64_Phdr)))) + bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32; + size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr); + if (unlikely (phnum > SIZE_MAX / phdr_size)) { free (buffer); goto no_memory; } - const size_t phdrsp_bytes = - phnum * MAX (sizeof (Elf32_Phdr), sizeof (Elf64_Phdr)); + const size_t phdrsp_bytes = phnum * phdr_size; phdrsp = malloc (phdrsp_bytes); - Elf32_Phdr (*p32)[phnum] = phdrsp; - Elf64_Phdr (*p64)[phnum] = phdrsp; if (unlikely (phdrsp == NULL)) { free (buffer); @@ -221,6 +215,8 @@ elf_from_remote_memory (GElf_Addr ehdr_vma, GElf_Off segments_end_mem = 0; GElf_Addr loadbase = ehdr_vma; bool found_base = false; + Elf32_Phdr (*p32)[phnum] = phdrsp; + Elf64_Phdr (*p64)[phnum] = phdrsp; switch (ehdr.e32.e_ident[EI_CLASS]) { /* Sanity checks segments and calculates segment_end, diff --git a/src/ChangeLog b/src/ChangeLog index e6744017f..f57788563 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2015-10-07 Mark Wielaard + + * unstrip.c (MAX): Removed. + (find_alloc_sections_prelink): Allocate exact amount of bytes for + shdrs. + 2015-10-05 Chih-Hung Hsieh * unstrip.c (find_alloc_sections_prelink): Do not allocate diff --git a/src/unstrip.c b/src/unstrip.c index 2a35decac..b725987c4 100644 --- a/src/unstrip.c +++ b/src/unstrip.c @@ -54,10 +54,6 @@ # define _(str) gettext (str) #endif -#ifndef MAX -# define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - /* Name and version of program. */ static void print_version (FILE *stream, struct argp_state *state); ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; @@ -1017,15 +1013,13 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"), ".gnu.prelink_undo"); - if (unlikely ((shnum - 1) > - SIZE_MAX / MAX (sizeof (Elf32_Shdr), sizeof (Elf64_Shdr)))) + bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32; + size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr); + if (unlikely ((shnum - 1) > SIZE_MAX / shsize)) error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"), (size_t) shnum, ".gnu.prelink_undo"); - const size_t shdr_bytes = - (shnum - 1) * MAX (sizeof (Elf32_Shdr), sizeof (Elf64_Shdr)); + const size_t shdr_bytes = (shnum - 1) * shsize; void *shdr = xmalloc (shdr_bytes); - Elf32_Shdr (*s32)[shnum - 1] = shdr; - Elf64_Shdr (*s64)[shnum - 1] = shdr; dst.d_buf = shdr; dst.d_size = shdr_bytes; ELF_CHECK (gelf_xlatetom (main, &dst, &src, @@ -1036,7 +1030,9 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, for (size_t i = 0; i < shnum - 1; ++i) { struct section *sec = &undo_sections[undo_nalloc]; - if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) + Elf32_Shdr (*s32)[shnum - 1] = shdr; + Elf64_Shdr (*s64)[shnum - 1] = shdr; + if (class32) { #define COPY(field) sec->shdr.field = (*s32)[i].field COPY (sh_name);