[PATCH] elf: Limit program header count to 64 [BZ #21265]

Florian Weimer fweimer@redhat.com
Fri Feb 13 08:01:13 GMT 2026


* Carlos O'Donell:

> On 2/12/26 12:05 PM, Florian Weimer wrote:
>> * Adhemerval Zanella Netto:
>> 
>>>> Reviewed-by: gaoxiang <gaoxiang@kylinos.cn>
>>>> Signed-off-by: litenglong <litenglong@kylinos.cn>
>>>>
>>>> Change-Id: I38bcbb179fdfd5134f3a3d9b6a473f3cf62c7afe
>>>> ---
>>>>   elf/dl-load.c | 6 ++++++
>>>>   1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/elf/dl-load.c b/elf/dl-load.c
>>>> index 7355eef..7bd8033 100644
>>>> --- a/elf/dl-load.c
>>>> +++ b/elf/dl-load.c
>>>> @@ -1099,6 +1099,12 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
>>>>       {
>>>>       /* Scan the program header table, collecting its load commands.  */
>>>> +    /* Reject unreasonable e_phnum values to prevent stack overflow via VLA. */
>>>> +    if (__glibc_unlikely (l->l_phnum > 64))
>>>> +      {
>>>> +        errstring = N_("too many program headers");
>>>> +        goto lose;
>>>> +      }
>>>
>>> This might potentially break loading of well-formed ELF objects. Also,
>>> there is other alloca that are controlled by ELF header information.
>>>
>>> The issue would be mitigated by -fstack-clash-protection, although it
>>> not supported on all ABIs. I think a best course of action is either
>>> use mmap direct to allocate a temporary buffer (maybe something similar
>>> to elf/dl-minimal-malloc.c, but with user-provided state).
>> I think we can iterate over the program headers in _dl_map_segments
>> (with a suitable abstraction).  There's no sorting involved, so we don't
>> need to make a copy of the load segments.  The additional performance
>> should be pretty minimal.
>
> Agreed, we're just walking the list roughly twice, and we'd want to avoid
> calling mmap more times than we need.
>
> 1. First iteration to compute maplength and do a MAP_FIXED mapping.
> 2. Second iteration to map loaded objects into place.
>
> It requires refactoring _dl_map_sgements and _dl_map_object_from_fd and
> exposing something you can iterate.
>
> Do you have any advice for litenglong?

My suggestion for refactoring this:

1. Define a struct dl_pt_load_iterator (to elf/dl-load.h, perhaps) that
   keeps state for the iteration.  There could be a struct loadcmd field
   in the new struct that keeps track of the same information as before.

2. Implement a function _dl_pt_load_iterator_init and
   _dl_pt_load_iterator_next that perform the iteration.  The
   _dl_pt_load_iterator_next function may have to look ahead on PT_LOAD
   segment.

3. Call _dl_pt_load_iterator_init before calling _dl_map_segments in
   _dl_map_object_from_fd.  Keep the existing loop in
   _dl_map_object_from_fd to compute maximums itself.

4. In _dl_map_segments, replace the loop over the load segments with the
   new iterator.

Thanks,
Florian



More information about the Libc-alpha mailing list