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);
>  }
>

Reply via email to