[binutils-gdb] PR 34049 buffer overflow in xcoff_link_add_symbols

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=7a089e0302382f4d4e077941156e1eaa68d01393

commit 7a089e0302382f4d4e077941156e1eaa68d01393
Author: Alan Modra <[email protected]>
Date:   Mon Apr 6 22:58:22 2026 +0930

    PR 34049 buffer overflow in xcoff_link_add_symbols
    
    The fact that coffcode.h:coff_set_alignment_hook for rs6000 removes
    sections can result in target_index > section_count.  Thus any array
    indexed by target_index must not be sized by section_count.
    
            PR ld/34049
            * xcofflink.c (xcoff_link_add_symbols): Size reloc_info array
            using max target_index.

Diff:
---
 bfd/xcofflink.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index 1781182fa6a..7f1c0df760f 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -1335,6 +1335,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
   } *reloc_info = NULL;
   bfd_size_type amt;
   unsigned short visibility;
+  unsigned int max_target_index;
 
   keep_syms = obj_coff_keep_syms (abfd);
 
@@ -1398,7 +1399,19 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
      order by VMA within a given section, so we handle this by
      scanning along the relocs as we process the csects.  We index
      into reloc_info using the section target_index.  */
-  amt = abfd->section_count + 1;
+  max_target_index = 0;
+  for (o = abfd->section_last; o != NULL; o = o->prev)
+    if (o->target_index != 0)
+      {
+	/* The last section added from the object file will have the
+	   highest target_index.  See coffgen.c coff_real_object_p and
+	   make_a_section_from_file.  Sections added by
+	   xcoff_link_create_extra_sections will have a zero
+	   target_index.  */
+	max_target_index = o->target_index;
+	break;
+      }
+  amt = max_target_index + 1;
   amt *= sizeof (struct reloc_info_struct);
   reloc_info = bfd_zmalloc (amt);
   if (reloc_info == NULL)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.