print_debug_frame_section called alloca for every CIE in the section and kept them on a list. The number of CIEs depends only on the size of the input file, so a large .eh_frame or .debug_frame exhausts the stack.
Use xmalloc and free the list on every exit path. Signed-off-by: Mohammed Mustafa <[email protected]> --- v2: Don't use the cleanup attribute. Free the list explicitly at the end of the function and on the early-exit paths. struct cieinfo stays local to the function. src/readelf.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/readelf.c b/src/readelf.c --- a/src/readelf.c +++ b/src/readelf.c @@ -6876,7 +6876,7 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, invalid_data: error (0, 0, _("invalid data in section [%zu] '%s'"), elf_ndxscn (scn), scnname); - return; + goto out; } /* At the beginning there must be a CIE. There can be multiple, @@ -7058,7 +7058,7 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, if (likely (ptr_size == 4 || ptr_size == 8)) { - struct cieinfo *newp = alloca (sizeof (*newp)); + struct cieinfo *newp = xmalloc (sizeof (*newp)); newp->cie_offset = offset; newp->augmentation = augmentation; newp->fde_encoding = fde_encoding; @@ -7080,7 +7080,7 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, if (unlikely (cie == NULL)) { puts ("invalid CIE reference in FDE"); - return; + goto out; } /* Initialize from CIE data. */ @@ -7213,6 +7213,14 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, fde_encoding, dwflmod, ebl, ehdr, dbg); readp = cieend; } + + out: + while (cies != NULL) + { + struct cieinfo *next = cies->next; + free (cies); + cies = next; + } } -- 2.53.0
