[binutils-gdb] PR 33223 ppc64: segfault on unknown relocation
Alan Modra
amodra@sourceware.org
Tue Jul 29 13:11:34 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8fd6a9c70b4b67541dbafba64d0e215eada05ff1
commit 8fd6a9c70b4b67541dbafba64d0e215eada05ff1
Author: Alan Modra <amodra@gmail.com>
Date: Tue Jul 29 10:39:51 2025 +0930
PR 33223 ppc64: segfault on unknown relocation
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.
Diff:
---
bfd/elf64-ppc.c | 40 +++++++++++++++++++------------------
ld/testsuite/ld-powerpc/elfv2-2so.d | 2 +-
2 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index e6c90a68b82..78680630c6e 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -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)
diff --git a/ld/testsuite/ld-powerpc/elfv2-2so.d b/ld/testsuite/ld-powerpc/elfv2-2so.d
index 56b143428fd..18bc87f09ac 100644
--- a/ld/testsuite/ld-powerpc/elfv2-2so.d
+++ b/ld/testsuite/ld-powerpc/elfv2-2so.d
@@ -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.*
More information about the Binutils-cvs
mailing list