[PATCH v2] elf: Avoid linker crash on corrupt .eh_frame section

H.J. Lu hjl.tools@gmail.com
Tue Sep 23 21:01:05 GMT 2025


On Wed, Sep 24, 2025 at 4:46 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Tue, Sep 23, 2025 at 10:50 PM Jan Beulich <jbeulich@suse.com> wrote:
> >
> > On 23.09.2025 04:23, H.J. Lu wrote:
> > > Return false on corrupt .eh_frame section.  Cap the .eh_frame section
> > > alignment to the larger of the section size and the pointer size.
> >
> > Like for patch 2, I'm unconvinced of it being a good idea to build in
> > heuristics like this. What if someone feels a need to align .eh_frame
> > to, say, a page boundary?
>
> .eh_frame section is special:
>
>      eh_alignment = ((1 << o->alignment_power)
>                       * bfd_octets_per_byte (output_bfd, o));
>       /* Skip over zero terminator, and prevent empty sections from
>          adding alignment padding at the end.  */
>       for (i = o->map_tail.s; i != NULL; i = i->map_tail.s)
>         if (i->size == 0)
>           i->flags |= SEC_EXCLUDE;
>         else if (i->size > 4)
>           break;
>       /* The last non-empty eh_frame section doesn't need padding.  */
>       if (i != NULL)
>         i = i->map_tail.s;
>       /* Any prior sections must pad the last FDE out to the output
>          section alignment.  Otherwise we might have zero padding
>          between sections, which would be seen as a terminator.  */
>       for (; i != NULL; i = i->map_tail.s)
>         if (i->size == 4)
>           /* All but the last zero terminator should have been removed.  */
>           BFD_FAIL ();
>         else
>           {
>             bfd_size_type size
>               = (i->size + eh_alignment - 1) & -eh_alignment;
>
> If .eh_frame section alignment is larger than the section size,
> we will get buffer overflow.
>
>             if (i->size != size)
>               {
>                 i->size = size;
>                 changed = 1;
>                 eh_changed = 1;
>               }
>           }
>
> > Also, please format unsigned long-s using %lu or (here) %lx. Especially
> > when values get large, imo printing them as decimal is unhelpful.
>
> Will do.
>
> > Finally - why would .eh_frame be special in this regard? What about,
> > say, .sframe?
> >
>
> .sframe section doesn't do the code above.
>
> --
> H.J.

Normally, .eh_frame section is aligned to 8 or 4 bytes, depending on ELF
class.  But linker may add alignment padding at the end of .eh_frame
section.  If .eh_frame section alignment is larger than the section size,
alignment padding will go beyond the .eh_frame section size.  Cap the
.eh_frame section alignment to the larger of the section size and the
pointer size.  Section size is checked since the .eh_frame section
alignment may be larger than ELF class size.  Otherwise, Linux/x86-64
will get these test failures:

./ld-new: tmpdir/eh3.o: warning: ignore .eh_frame section alignment (16), limit
it to 8
FAIL: ld-elf/eh3

../binutils/objdump: tmpdir/dump: warning: ignore .eh_frame section alignment (8
), limit it to 4
FAIL: ld-x86-64/pr18160

./ld-new: tmpdir/simple-x32.o: warning: ignore .eh_frame section alignment (8),
limit it to 4
FAIL: X32 DSO from x86-64 object

Also return false on corrupt .eh_frame section.

PR ld/33453
* elf-bfd.h (ABI_64_P): New.
* elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Return false
on corrupt .eh_frame section.
* elf.c (_bfd_elf_make_section_from_shdr): Limit .eh_frame section
alignment.
* elfxx-mips.c (ABI_64_P): Removed.
* elfxx-sparc.c (ABI_64_P): Likewise.
* elfxx-tilegx.c (ABI_64_P): Likewise.
* elfxx-x86.h (ABI_64_P): Likewise.

OK for master?

-- 
H.J.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v2-0001-elf-Avoid-linker-crash-on-corrupt-.eh_frame-secti.patch
Type: text/x-patch
Size: 5940 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20250924/01a4136d/attachment.bin>


More information about the Binutils mailing list