]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR 33223 ppc64: segfault on unknown relocation
authorAlan Modra <amodra@gmail.com>
Tue, 29 Jul 2025 01:09:51 +0000 (10:39 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 29 Jul 2025 12:55:21 +0000 (22:25 +0930)
Bounds check accesses to ppc64_elf_howto_table and don't dereference a
NULL howto.  I think this catches all cases where that might happen.

PR 33223
bfd/
* elf64-ppc.c (ppc64_elf_info_to_howto): Consolidate error handling.
(ppc64_elf_check_relocs): Tidy error messages.
(ppc64_elf_relocate_section): Don't segfault when attempting to
report an unsupported relocation.  Don't pass a NULL howto to
_bfd_clear_contents.
ld/
* testsuite/ld-powerpc/elfv2-2so.d: Adjust to suit error message
change.

bfd/elf64-ppc.c
ld/testsuite/ld-powerpc/elfv2-2so.d

index e6c90a68b82dec39f00e5d599485c55c79aa8d44..78680630c6ed3b4eb7ad1af3a21af8e4c5c9f582 100644 (file)
@@ -1379,7 +1379,8 @@ ppc64_elf_info_to_howto (bfd *abfd, arelent *cache_ptr,
     ppc_howto_init ();
 
   type = ELF64_R_TYPE (dst->r_info);
-  if (type >= ARRAY_SIZE (ppc64_elf_howto_table))
+  if (type >= ARRAY_SIZE (ppc64_elf_howto_table)
+      || ppc64_elf_howto_table[type] == NULL)
     {
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
@@ -1388,15 +1389,6 @@ ppc64_elf_info_to_howto (bfd *abfd, arelent *cache_ptr,
       return false;
     }
   cache_ptr->howto = ppc64_elf_howto_table[type];
-  if (cache_ptr->howto == NULL || cache_ptr->howto->name == NULL)
-    {
-      /* xgettext:c-format */
-      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
-                         abfd, type);
-      bfd_set_error (bfd_error_bad_value);
-      return false;
-    }
-
   return true;
 }
 
@@ -5104,7 +5096,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
              if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
                ppc_howto_init ();
              /* xgettext:c-format */
-             info->callbacks->einfo (_("%H: %s reloc unsupported "
+             info->callbacks->einfo (_("%H: %s unsupported "
                                        "in shared libraries and PIEs\n"),
                                      abfd, sec, rel->r_offset,
                                      ppc64_elf_howto_table[r_type]->name);
@@ -5274,7 +5266,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
          if (ppc64_sec->sec_type != sec_toc
              || rel->r_offset % 8 != 0)
            {
-             info->callbacks->einfo (_("%H: %s reloc unsupported here\n"),
+             info->callbacks->einfo (_("%H: %s unsupported here\n"),
                                      abfd, sec, rel->r_offset,
                                      ppc64_elf_howto_table[r_type]->name);
              bfd_set_error (bfd_error_bad_value);
@@ -15685,9 +15677,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 
       if (sec != NULL && discarded_section (sec))
        {
-         _bfd_clear_contents (ppc64_elf_howto_table[r_type],
-                              input_bfd, input_section,
-                              contents, rel->r_offset);
+         if (r_type < ARRAY_SIZE (ppc64_elf_howto_table)
+             && ppc64_elf_howto_table[r_type] != NULL)
+           _bfd_clear_contents (ppc64_elf_howto_table[r_type],
+                                input_bfd, input_section,
+                                contents, rel->r_offset);
          wrel->r_offset = rel->r_offset;
          wrel->r_info = 0;
          wrel->r_addend = 0;
@@ -15750,6 +15744,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
         relocs are used with non-tls syms.  */
       if (r_symndx != STN_UNDEF
          && r_type != R_PPC64_NONE
+         && r_type < ARRAY_SIZE (ppc64_elf_howto_table)
+         && ppc64_elf_howto_table[r_type] != NULL
          && (h == NULL
              || h->elf.root.type == bfd_link_hash_defined
              || h->elf.root.type == bfd_link_hash_defweak)
@@ -16865,9 +16861,15 @@ ppc64_elf_relocate_section (bfd *output_bfd,
       switch (r_type)
        {
        default:
-         /* xgettext:c-format */
-         _bfd_error_handler (_("%pB: %s unsupported"),
-                             input_bfd, ppc64_elf_howto_table[r_type]->name);
+         if (r_type < ARRAY_SIZE (ppc64_elf_howto_table)
+             && ppc64_elf_howto_table[r_type] != NULL)
+           /* xgettext:c-format */
+           _bfd_error_handler (_("%pB: %s unsupported"),
+                               input_bfd, ppc64_elf_howto_table[r_type]->name);
+         else
+           /* xgettext:c-format */
+           _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                               input_bfd, r_type);
 
          bfd_set_error (bfd_error_bad_value);
          ret = false;
@@ -17909,7 +17911,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
         because such sections are not SEC_ALLOC and thus ld.so will
         not process them.  */
-      howto = ppc64_elf_howto_table[(int) r_type];
+      howto = ppc64_elf_howto_table[r_type];
       if (unresolved_reloc
          && !((input_section->flags & SEC_DEBUGGING) != 0
               && h->elf.def_dynamic)
index 56b143428fdb8211eb6bdb8a3a991abaf1bb8336..18bc87f09ac769771ac657d2327080999e2fcf82 100644 (file)
@@ -2,4 +2,4 @@
 #source: elfv2-2b.s
 #as: -a64
 #ld: -melf64ppc -shared -e f1
-#error: .* R_PPC64_ADDR64_LOCAL reloc unsupported in shared libraries and PIEs.*
+#error: .* R_PPC64_ADDR64_LOCAL unsupported in shared libraries and PIEs.*