]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: Return error for invalid relocation offset
authorH.J. Lu <hjl.tools@gmail.com>
Sun, 9 Feb 2025 07:13:38 +0000 (15:13 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Sun, 9 Feb 2025 22:35:34 +0000 (06:35 +0800)
Return error if relocation offset + relocation size > section size.

bfd/

PR ld/32665
* elf32-i386.c (elf_i386_scan_relocs): Return error for invalid
relocation offset.
* elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.

ld/

PR ld/32665
* testsuite/ld-x86-64/pr32665.err: New file.
* testsuite/ld-x86-64/pr32665.o.bz2: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/32665 test.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/testsuite/ld-x86-64/pr32665.err [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr32665.o.bz2 [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 81301bf3a57a7cdf3010a45c6dba7721e63e07ef..701cb6d5473431307b0f8b536165f524b780fb32 100644 (file)
@@ -1531,6 +1531,7 @@ elf_i386_scan_relocs (bfd *abfd,
       const char *name;
       bool size_reloc;
       bool no_dynreloc;
+      reloc_howto_type *howto;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -1547,6 +1548,17 @@ elf_i386_scan_relocs (bfd *abfd,
          goto error_return;
        }
 
+      howto = elf_i386_rtype_to_howto (r_type);
+      if (rel->r_offset + bfd_get_reloc_size (howto) > sec->size)
+       {
+         /* xgettext:c-format */
+         _bfd_error_handler
+           (_("%pB: bad reloc offset (%#" PRIx32 " > %#" PRIx32 ") for"
+              " section `%pA'"), abfd, (uint32_t) rel->r_offset,
+            (uint32_t) sec->size, sec);
+         goto error_return;
+       }
+
       if (r_symndx < symtab_hdr->sh_info)
        {
          /* A local symbol.  */
index bb42ed5bd632f532c0208c5e39d6a91914e189b6..feb8827b3c1d116f7ef12bad367a3e3d0c681eed 100644 (file)
@@ -2441,6 +2441,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
       bool size_reloc;
       bool converted_reloc;
       bool no_dynreloc;
+      reloc_howto_type *howto;
 
       r_symndx = htab->r_sym (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -2457,6 +2458,17 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
          goto error_return;
        }
 
+      howto = elf_x86_64_rtype_to_howto (abfd, r_type);
+      if (rel->r_offset + bfd_get_reloc_size (howto) > sec->size)
+       {
+         /* xgettext:c-format */
+         _bfd_error_handler
+           (_("%pB: bad reloc offset (%#" PRIx64 " > %#" PRIx64 ") for"
+              " section `%pA'"), abfd, (uint64_t) rel->r_offset,
+            (uint64_t) sec->size, sec);
+         goto error_return;
+       }
+
       if (r_symndx < symtab_hdr->sh_info)
        {
          /* A local symbol.  */
diff --git a/ld/testsuite/ld-x86-64/pr32665.err b/ld/testsuite/ld-x86-64/pr32665.err
new file mode 100644 (file)
index 0000000..f539eb0
--- /dev/null
@@ -0,0 +1,3 @@
+#...
+.*tmpdir/pr32665.o: bad reloc offset \(0xf2ffffff01bc > 0x574\) for section `.text'
+#...
diff --git a/ld/testsuite/ld-x86-64/pr32665.o.bz2 b/ld/testsuite/ld-x86-64/pr32665.o.bz2
new file mode 100644 (file)
index 0000000..42695cb
Binary files /dev/null and b/ld/testsuite/ld-x86-64/pr32665.o.bz2 differ
index bcec5c1926a7985ea49e7ec58c8e001f59a03b1e..e4b9ebb033c483e1b31a6fbcb86beae2be5e4c20 100644 (file)
@@ -216,6 +216,11 @@ set x86_64tests {
     {"Build textrel-1" "-no-pie -melf_x86_64 -z nocopyreloc --warn-textrel"
      "tmpdir/textrel-1.so"
      "--64" { textrel-1b.s } {{ld "textrel-1.err"}} "textrel-1"}
+    {"Build pr32665"
+     "-melf_x86_64"
+     "" ""
+     { pr32665.o.bz2 }
+     {{ld "pr32665.err"}} "pr32665"}
 }
 
 run_ld_link_tests $x86_64tests