Hi Mustafa, Thanks for the patch, merged. The format of the patch is still broken such that git am cannot apply automatically but I was able to apply it by hand.
Aaron On Tue, Nov 10, 2026 at 6:14 AM mustafa <[email protected]> wrote: > > 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 is freed through its base pointer, because the array pointer > is advanced while parsing. The macro list is freed by free_mac_culist. > Both functions free their allocations on every exit path. > > Signed-off-by: Mohammed Mustafa <[email protected]> > --- > v2: Don't use the cleanup attribute. Free explicitly on all exit paths. > Free the original array pointer, not the advanced one. Drop the > free_ptr move. > > src/readelf.c | 40 ++++++++++++++++++++++++++++++---------- > 1 file changed, 30 insertions(+), 10 deletions(-) > > diff --git a/src/readelf.c b/src/readelf.c > --- a/src/readelf.c > +++ b/src/readelf.c > @@ -10068,6 +10068,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 +10132,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 +10142,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_base = xmalloc ((nculist + 1) * sizeof (*cus_base)); > + struct mac_culist *cus = cus_base; > /* Add sentinel. */ > cus[nculist].offset = data->d_size; > cus[nculist].files = (Dwarf_Files *) -1l; > @@ -10142,8 +10152,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 > @@ -10172,7 +10184,7 @@ print_debug_macinfo_section (Dwfl_Module > *dwflmod __attribute__ ((unused)), > printf (_("\ > %*s*** non-terminated string at end of section"), > level, ""); > - return; > + goto out; > } > > if (opcode == DW_MACINFO_define) > @@ -10199,7 +10211,7 @@ print_debug_macinfo_section (Dwfl_Module > *dwflmod __attribute__ ((unused)), > printf (_("\ > %*s*** missing DW_MACINFO_start_file argument at end of section"), > level, ""); > - return; > + goto out; > } > get_uleb128 (u128_2, readp, readendp); > > @@ -10241,6 +10253,9 @@ print_debug_macinfo_section (Dwfl_Module > *dwflmod __attribute__ ((unused)), > break; > } > } > + > + out: > + free (cus_base); > } > > @@ -10282,7 +10297,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; > @@ -10304,7 +10319,7 @@ print_debug_macro_section (Dwfl_Module > *dwflmod __attribute__ ((unused)), > { > invalid_data: > error (0, 0, _("invalid data")); > - return; > + goto out; > } > const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp); > printf (_(" Version: %" PRIu16 "\n"), vers); > @@ -10314,7 +10329,7 @@ print_debug_macro_section (Dwfl_Module > *dwflmod __attribute__ ((unused)), > if (vers != 4 && vers != 5) > { > printf (_(" unknown version, cannot parse section\n")); > - return; > + goto out; > } > > if (readp + 1 > readendp) > @@ -10526,6 +10541,9 @@ print_debug_macro_section (Dwfl_Module > *dwflmod __attribute__ ((unused)), > putchar_unlocked ('\n'); > } > } > + > + out: > + free_mac_culist (culist); > } >
