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 through a cleanup attribute. This needs
struct cieinfo at file scope.

Signed-off-by: mohammed mustafa <[email protected]>
---
 src/readelf.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/src/readelf.c b/src/readelf.c
index ba47f361..12118b4f 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -6805,6 +6805,29 @@ print_encoding_base (const char *pfx, unsigned
int fde_encoding)
 }


+struct cieinfo
+{
+  ptrdiff_t cie_offset;
+  const char *augmentation;
+  unsigned int code_alignment_factor;
+  unsigned int data_alignment_factor;
+  uint8_t address_size;
+  uint8_t fde_encoding;
+  uint8_t lsda_encoding;
+  struct cieinfo *next;
+};
+
+static void
+free_cies (struct cieinfo **cies)
+{
+  while (*cies != NULL)
+    {
+      struct cieinfo *next = (*cies)->next;
+      free (*cies);
+      *cies = next;
+    }
+}
+
 static void
 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
                           Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
@@ -6850,17 +6873,7 @@ print_debug_frame_section (Dwfl_Module
*dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
            elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);

-  struct cieinfo
-  {
-    ptrdiff_t cie_offset;
-    const char *augmentation;
-    unsigned int code_alignment_factor;
-    unsigned int data_alignment_factor;
-    uint8_t address_size;
-    uint8_t fde_encoding;
-    uint8_t lsda_encoding;
-    struct cieinfo *next;
-  } *cies = NULL;
+  struct cieinfo *cies __attribute__ ((cleanup (free_cies))) = NULL;

   const unsigned char *readp = data->d_buf;
   const unsigned char *const dataend = ((unsigned char *) data->d_buf
@@ -7058,7 +7071,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;
-- 
2.53.0

Reply via email to