[binutils-gdb] PR 34038 null pointer dereference in elf_link_output_extsym
Alan Modra via Binutils-cvs <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c34038bc79db96395d3ebd4f231e9a98ba0e24df commit c34038bc79db96395d3ebd4f231e9a98ba0e24df Author: Joel Holdsworth <[email protected]> Date: Thu Apr 2 10:23:14 2026 -0700 PR 34038 null pointer dereference in elf_link_output_extsym When linking an ELF object file containing an STT_GNU_IFUNC symbol, elf_link_output_extsym() unconditionally calls the backend's elf_backend_finish_dynamic_symbol callback. On targets that do not support dynamic linking (and therefore do not define this callback), the function pointer is NULL, causing a segmentation fault. Add a NULL check for bed->elf_backend_finish_dynamic_symbol before the indirect call. This is consistent with the definition in elfxx-target.h which defaults this callback to 0 (NULL) for targets that do not override it. Found by AFL++ fuzzing of the ELF linker with mutated object files. Signed-off-by: Joel Holdsworth <[email protected]> Diff: --- bfd/elflink.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/bfd/elflink.c b/bfd/elflink.c index 70a1cd107aa..197c5759527 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11020,19 +11020,20 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) symbol. FIXME: Not calling elf_backend_finish_dynamic_symbol for forced local syms when non-shared is due to a historical quirk. STT_GNU_IFUNC symbol must go through PLT. */ - if ((h->type == STT_GNU_IFUNC - && h->def_regular - && !bfd_link_relocatable (flinfo->info)) - || ((h->dynindx != -1 - || h->forced_local) - && ((bfd_link_pic (flinfo->info) - && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak)) - || !h->forced_local) - && elf_hash_table (flinfo->info)->dynamic_sections_created)) - { - if (! ((*bed->elf_backend_finish_dynamic_symbol) - (flinfo->output_bfd, flinfo->info, h, &sym))) + if (((h->type == STT_GNU_IFUNC + && h->def_regular + && !bfd_link_relocatable (flinfo->info)) + || ((h->dynindx != -1 + || h->forced_local) + && ((bfd_link_pic (flinfo->info) + && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak)) + || !h->forced_local) + && elf_hash_table (flinfo->info)->dynamic_sections_created)) + && bed->elf_backend_finish_dynamic_symbol != NULL) + { + if (!bed->elf_backend_finish_dynamic_symbol (flinfo->output_bfd, + flinfo->info, h, &sym)) { eoinfo->failed = true; return false;