diff options
| author | Chih-Hung Hsieh <[email protected]> | 2015-10-06 15:53:15 -0700 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2015-10-07 22:44:41 +0200 |
| commit | 7eff36d5daa6ebca5e6399638a7643af105ae5b0 (patch) | |
| tree | 7bfd9c4a93f88135b9f42337d827948aa6b63cdb /src | |
| parent | daee4714ee3761e2d92f764a724e83875a79a3f0 (diff) | |
Do without union of variable length arrays.
Prepare to compile with clang.
A union like
{ T32 a32[n]; T64 a64[n]; } u;
is expanded to
size_t nbytes = n * MAX(sizeof(T32), sizeof(T64));
void *data = malloc(nbytes);
T32 (*a32)[n] = data;
T64 (*a64)[n] = data;
Signed-off-by: Chih-Hung Hsieh <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/readelf.c | 26 | ||||
| -rw-r--r-- | src/unstrip.c | 27 |
3 files changed, 43 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index daa76cf2..e6744017 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2015-10-05 Chih-Hung Hsieh <[email protected]> + + * unstrip.c (find_alloc_sections_prelink): Do not allocate + on stack union types with variable length arrays; use xmalloc + for such dynamic sized objects. + * readelf.c (handle_core_item): Likewise, but use alloca + for small variable size data object and add assert(count < 128). + 2015-10-05 Josh Stone <[email protected]> * Makefile.am (libld_elf_i386.so): Add AM_V_CCLD silencer. diff --git a/src/readelf.c b/src/readelf.c index 33274f35..fe7bc392 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -8370,6 +8370,9 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, unsigned int colno, size_t *repeated_size) { uint_fast16_t count = item->count ?: 1; + /* Ebl_Core_Item count is always a small number. + Make sure the backend didn't put in some large bogus value. */ + assert (count < 128); #define TYPES \ DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \ @@ -8379,11 +8382,16 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \ DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64) -#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name[count] - union { TYPES; } value; +#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name + typedef union { TYPES; } value_t; + void *data = alloca (count * sizeof (value_t)); +#undef DO_TYPE + +#define DO_TYPE(NAME, Name, hex, dec) \ + GElf_##Name *value_##Name __attribute__((unused)) = data + TYPES; #undef DO_TYPE - void *data = &value; size_t size = gelf_fsize (core, item->type, count, EV_CURRENT); size_t convsize = size; if (repeated_size != NULL) @@ -8414,7 +8422,7 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, #define DO_TYPE(NAME, Name, hex, dec) \ case ELF_T_##NAME: \ colno = print_core_item (colno, ',', WRAP_COLUMN, \ - 0, item->name, dec, value.Name[0]); \ + 0, item->name, dec, value_##Name[0]); \ break TYPES; #undef DO_TYPE @@ -8430,7 +8438,7 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, #define DO_TYPE(NAME, Name, hex, dec) \ case ELF_T_##NAME: \ colno = print_core_item (colno, ',', WRAP_COLUMN, \ - 0, item->name, hex, value.Name[0]); \ + 0, item->name, hex, value_##Name[0]); \ break TYPES; #undef DO_TYPE @@ -8520,8 +8528,8 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, { #define DO_TYPE(NAME, Name, hex, dec) \ case ELF_T_##NAME: \ - sec = value.Name[0]; \ - usec = value.Name[1]; \ + sec = value_##Name[0]; \ + usec = value_##Name[1]; \ break TYPES; #undef DO_TYPE @@ -8551,12 +8559,12 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, case 'c': assert (count == 1); colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name, - "%c", value.Byte[0]); + "%c", value_Byte[0]); break; case 's': colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name, - "%.*s", (int) count, value.Byte); + "%.*s", (int) count, value_Byte); break; case '\n': diff --git a/src/unstrip.c b/src/unstrip.c index d193708a..2a35deca 100644 --- a/src/unstrip.c +++ b/src/unstrip.c @@ -54,6 +54,10 @@ # 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; @@ -1013,13 +1017,17 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"), ".gnu.prelink_undo"); - union - { - Elf32_Shdr s32[shnum - 1]; - Elf64_Shdr s64[shnum - 1]; - } shdr; - dst.d_buf = &shdr; - dst.d_size = sizeof shdr; + if (unlikely ((shnum - 1) > + SIZE_MAX / MAX (sizeof (Elf32_Shdr), sizeof (Elf64_Shdr)))) + 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)); + 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, main_ehdr->e_ident[EI_DATA]) != NULL, _("cannot read '.gnu.prelink_undo' section: %s")); @@ -1030,7 +1038,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, struct section *sec = &undo_sections[undo_nalloc]; if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) { -#define COPY(field) sec->shdr.field = shdr.s32[i].field +#define COPY(field) sec->shdr.field = (*s32)[i].field COPY (sh_name); COPY (sh_type); COPY (sh_flags); @@ -1044,7 +1052,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, #undef COPY } else - sec->shdr = shdr.s64[i]; + sec->shdr = (*s64)[i]; if (sec->shdr.sh_flags & SHF_ALLOC) { sec->shdr.sh_addr += bias; @@ -1057,6 +1065,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, } qsort (undo_sections, undo_nalloc, sizeof undo_sections[0], compare_sections_nonrel); + free (shdr); } bool fail = false; |
