]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR 34038 null pointer dereference in elf_link_output_extsym
authorJoel Holdsworth <jholdsworth@nvidia.com>
Thu, 2 Apr 2026 17:23:14 +0000 (10:23 -0700)
committerAlan Modra <amodra@gmail.com>
Thu, 2 Apr 2026 23:28:55 +0000 (09:58 +1030)
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 <jholdsworth@nvidia.com>
bfd/elflink.c

index 70a1cd107aaf4c02e950e99b4e4e61438fdddbd4..197c57595274b921df34e4bef2db5ec8db11ed60 100644 (file)
@@ -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;