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

Alan Modra amodra@gmail.com
Wed Aug 12 08:07:19 GMT 2026


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


More information about the Binutils mailing list