Re: [PATCH] microblaze: don't index the local symbol cache with a global symbol index

Alan Modra <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
On Mon, Aug 10, 2026 at 01:36:33AM -0400, Sam Price wrote:
> Please see attached patch file.
> 
> microblaze_elf_relax_section() was copied from
> sh_elf_relax_delete_bytes() in 2009 (7ba29e2a41) but the copy dropped
> a bounds check that was already present in the sh original.  This adds
> the missing two-line guard from bfd/elf32-sh.c:1227-1228, preventing
> an out-of-bounds read that silently corrupts relocation addends.

The patch looks good to me.  As you correctly point out, the
symtab_hdr->contents buffer is supposed to only contain local syms,
so indexing at symtab_hdr->sh_info or above is wrong.  What's more,
none of the code in microblaze_elf_relax_section needs to re-read
global syms so you might like to add the following tidy-up to your
patch.

diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
index 5300f8d4d87..0723f98fa88 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
@@ -1862,11 +1862,13 @@ microblaze_elf_relax_section (bfd *abfd,
   /* Get symbols for this section.  */
   symtab_hdr = &elf_symtab_hdr (abfd);
   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
-  symcount =  symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
-  if (isymbuf == NULL)
-    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
-				    0, NULL, NULL, NULL);
-  BFD_ASSERT (isymbuf != NULL);
+  if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+    {
+      isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info,
+				      0, NULL, NULL, NULL);
+      if (isymbuf == NULL)
+	goto error_return;
+    }
 
   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
   if (internal_relocs == NULL)
@@ -2285,7 +2287,7 @@ microblaze_elf_relax_section (bfd *abfd,
 	}
 
       /* Adjust the local symbols defined in this section.  */
-      isymend = isymbuf + symtab_hdr->sh_info;
+      isymend = PTR_ADD (isymbuf, symtab_hdr->sh_info);
       for (isym = isymbuf; isym < isymend; isym++)
 	{
 	  if (isym->st_shndx == shndx)
@@ -2297,7 +2299,6 @@ microblaze_elf_relax_section (bfd *abfd,
 	}
 
       /* Now adjust the global symbols defined in this section.  */
-      isym = isymbuf + symtab_hdr->sh_info;
       symcount =  (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
       for (sym_index = 0; sym_index < symcount; sym_index++)
 	{

-- 
Alan Modra
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.