]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
pr 34159, buffer overflow in fr30_elf_i32_reloc
authorAlan Modra <amodra@gmail.com>
Sun, 24 May 2026 04:54:59 +0000 (14:24 +0930)
committerAlan Modra <amodra@gmail.com>
Sun, 24 May 2026 04:54:59 +0000 (14:24 +0930)
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.

bfd/elf32-fr30.c

index 1460aed77305f03b3b22f350ac491d690c4b5df6..75ec074d23be902e424cd328df91a09055a953ab 100644 (file)
@@ -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