>From f22df508fce15d79820aaacd5300f0e916f52e5c Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 8 Oct 2015 00:16:03 +0200 Subject: [PATCH] Allocate exact amount of bytes for phdrs and shdrs. Signed-off-by: Mark Wielaard --- libdwfl/ChangeLog | 10 +++++++ libdwfl/dwfl_module_getdwarf.c | 51 ++++++++++++++++++------------------ libdwfl/dwfl_segment_report_module.c | 13 ++++----- libdwfl/elf-from-memory.c | 16 +++++------ src/ChangeLog | 6 +++++ src/unstrip.c | 18 +++++-------- 6 files changed, 61 insertions(+), 53 deletions(-) diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 949a372..ee41405 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 c339040..a359057 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 92f691d..ca86c31 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 5be21bb..dd42e95 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 e674401..f577885 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 2a35dec..b725987 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); -- 2.4.3