PR 34159, buffer overflow in fr30_elf_i32_reloc

Message ID ahLey0Z28PKBcUca@squeak.grove.modra.org
State New
Headers
Series PR 34159, buffer overflow in fr30_elf_i32_reloc |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply

Commit Message

Alan Modra May 24, 2026, 11:19 a.m. UTC
  Stop the fuzzed object file buffer overflow, and remove a FIXME.

	* elf32-fr30.c (fr30_elf_i20_reloc, fr30_elf_i32_reloc): Handle
	ld -r using bfd_elf_generic_reloc.  Sanity check reloc offset.
  

Patch

diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c
index 1460aed7730..75ec074d23b 100644
--- a/bfd/elf32-fr30.c
+++ b/bfd/elf32-fr30.c
@@ -238,24 +238,18 @@  fr30_elf_i20_reloc (bfd *abfd,
 		    void * data,
 		    asection *input_section,
 		    bfd *output_bfd,
-		    char **error_message ATTRIBUTE_UNUSED)
+		    char **error_message)
 {
   bfd_vma relocation;
   unsigned long x;
 
-  /* This part is from bfd_elf_generic_reloc.  */
-  if (output_bfd != (bfd *) NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (! reloc_entry->howto->partial_inplace
-	  || reloc_entry->addend == 0))
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
   if (output_bfd != NULL)
-    /* FIXME: See bfd_perform_relocation.  Is this right?  */
-    return bfd_reloc_ok;
+    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+				  input_section, output_bfd, error_message);
+
+  if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+				  input_section, reloc_entry->address))
+    return bfd_reloc_outofrange;
 
   relocation =
     symbol->value
@@ -282,23 +276,18 @@  fr30_elf_i32_reloc (bfd *abfd,
 		    void * data,
 		    asection *input_section,
 		    bfd *output_bfd,
-		    char **error_message ATTRIBUTE_UNUSED)
+		    char **error_message)
 {
   bfd_vma relocation;
 
-  /* This part is from bfd_elf_generic_reloc.  */
-  if (output_bfd != (bfd *) NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (! reloc_entry->howto->partial_inplace
-	  || reloc_entry->addend == 0))
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
   if (output_bfd != NULL)
-    /* FIXME: See bfd_perform_relocation.  Is this right?  */
-    return bfd_reloc_ok;
+    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+				  input_section, output_bfd, error_message);
+
+  if (reloc_entry->address + 2 < 2
+      || !bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+				     input_section, reloc_entry->address + 2))
+    return bfd_reloc_outofrange;
 
   relocation =
     symbol->value