print_debug_macinfo_section and print_debug_macro_section called alloca for each CU that has a macro attribute, and print_debug_macinfo_section also allocated an array with one entry per CU. The number of CUs is bounded only by the size of the input file, so a large .debug_info exhausts the stack.
Use xmalloc. The macinfo list is freed as it is copied into the array, the array and the macro list are freed through cleanup attributes. Move free_ptr to the top of the file so these functions can use it. Signed-off-by: mohammed mustafa <[email protected]> --- src/readelf.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/readelf.c b/src/readelf.c index 12118b4f..21db75ce 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -168,6 +168,12 @@ static struct argp argp = options, parse_opt, args_doc, doc, NULL, NULL, NULL }; +static void +free_ptr (void *p) +{ + free (*(void **) p); +} + /* If non-null, the section from which we should read to (compressed) ELF. */ static const char *elf_input_section = NULL; @@ -10068,6 +10074,16 @@ struct mac_culist struct mac_culist *next; }; +static void +free_mac_culist (struct mac_culist **culist) +{ + while (*culist != NULL) + { + struct mac_culist *next = (*culist)->next; + free (*culist); + *culist = next; + } +} static int mac_compare (const void *p1, const void *p2) @@ -10122,7 +10138,7 @@ print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)), if (dwarf_formudata (&attr, &macoff) != 0) continue; - struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp)); + struct mac_culist *newp = xmalloc (sizeof (*newp)); newp->die = cudie; newp->offset = macoff; newp->files = NULL; @@ -10132,8 +10148,8 @@ print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)), } /* Convert the list into an array for easier consumption. */ - struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1) - * sizeof (*cus)); + struct mac_culist *cus __attribute__ ((cleanup (free_ptr))) + = xmalloc ((nculist + 1) * sizeof (*cus)); /* Add sentinel. */ cus[nculist].offset = data->d_size; cus[nculist].files = (Dwarf_Files *) -1l; @@ -10142,8 +10158,10 @@ print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)), for (size_t cnt = nculist - 1; culist != NULL; --cnt) { assert (cnt < nculist); + struct mac_culist *next = culist->next; cus[cnt] = *culist; - culist = culist->next; + free (culist); + culist = next; } /* Sort the array according to the offset in the .debug_macinfo @@ -10267,7 +10285,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)), Dwarf_Off offset; Dwarf_Off ncu = 0; size_t hsize; - struct mac_culist *culist = NULL; + struct mac_culist *culist __attribute__ ((cleanup (free_mac_culist))) = NULL; while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0) { Dwarf_Die cudie; @@ -10282,7 +10300,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)), if (dwarf_formudata (&attr, &lineoff) != 0) continue; - struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp)); + struct mac_culist *newp = xmalloc (sizeof (*newp)); newp->die = cudie; newp->offset = lineoff; newp->files = NULL; @@ -11860,12 +11878,6 @@ convert (Elf *core, Elf_Type type, uint_fast16_t count, typedef uint8_t GElf_Byte; -static void -free_ptr (void *p) -{ - free (*(void **) p); -} - static unsigned int handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc, unsigned int colno, size_t *repeated_size) -- 2.53.0
