From: H.J. Lu Date: Sun, 9 Feb 2025 07:13:38 +0000 (+0800) Subject: x86: Return error for invalid relocation offset X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d4d66eb19fd5ace50e1d40f53f14e76fe8b8963d;p=thirdparty%2Fbinutils-gdb.git x86: Return error for invalid relocation offset 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 --- diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 81301bf3a57..701cb6d5473 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -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. */ diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index bb42ed5bd63..feb8827b3c1 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -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 index 00000000000..f539eb07433 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr32665.err @@ -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 index 00000000000..42695cb8577 Binary files /dev/null and b/ld/testsuite/ld-x86-64/pr32665.o.bz2 differ diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index bcec5c1926a..e4b9ebb033c 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -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