https://sourceware.org/bugzilla/show_bug.cgi?id=34987
Bug ID: 34987
Summary: RISC-V: ld applies relocations outside the section
without a bounds check
Product: binutils
Version: 2.48 (HEAD)
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: harshit7kr at gmail dot com
Target Milestone: ---
riscv_elf_relocate_section and the RISC-V relaxation helpers access
section contents at rel->r_offset without checking that the relocated
field lies inside the input section. A malformed relocatable object can
therefore make ld read and write outside the section buffer. Seen on
master (49465fb034a8):
- A relocation (e.g. R_RISCV_SET32) whose r_offset is outside the
section is applied anyway. The link can still succeed with exit
status 0 and no diagnostic, while the write lands in other linker
memory and can change the output file.
- R_RISCV_SUB_ULEB128 at the section end makes perform_relocation
pass (size_t) -1 to memset; ld aborts with
"double free or corruption (out)".
- R_RISCV_TLSDESC_CALL at the section end makes
riscv_resolve_tlsdesc_lo_relocs write 4 bytes past the section
(AddressSanitizer: heap-buffer-overflow in bfd_putl32).
- The relaxation helpers only BFD_ASSERT their spans, which logs an
error and carries on.
- An unterminated ULEB128 field is linked silently with exit status 0.
Expected: ld rejects such input with a diagnostic, e.g.
ld: foo.o: bad reloc offset (0x10 + 0x1 > 0x10) for section `.text'
ld: final link failed: bad value
Reproducers: the patch series below adds DejaGnu tests for each case
(ld/testsuite/ld-riscv-elf/*-bounds*, uleb128-*, riscv-reloc-offset.exp).
On master the error cases fail, several by crashing ld; with the series
they pass.
Patch series (5 patches): will follow in a comment once posted.
Configuration used: --target=riscv64-elf, riscv32-elf and
riscv64-linux-gnu; host x86_64-pc-linux-gnu.
--
You are receiving this mail because:
You are on the CC list for the bug.