https://sourceware.org/bugzilla/show_bug.cgi?id=29682
Bug ID: 29682
Summary: Out-of-bound read in function `mips16_gprel_reloc`
Product: binutils
Version: 2.40 (HEAD)
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: binutils
Assignee: unassigned at sourceware dot org
Reporter: r3tr0spect2019 at gmail dot com
Target Milestone: ---
Created attachment 14398
--> https://sourceware.org/bugzilla/attachment.cgi?id=14398&action=edit
PoC
# Reproduce
```bash
cd binutils-gdb
git reset --hard 1d4e62f498b1340569fd58c401f98c287cb5d071
mkdir build && cd build
../configure --disable-gdb --disable-gdbserver --disable-gdbsupport
--disable-libdecnumber --disable-readline --disable-sim --disable-libbacktrace
--disable-gas --disable-ld --disable-werror --enable-targets=all
CPPFLAGS=-DDEBUG CFLAGS="-g -O0 -fsanitize=address"
make all-binutils MAKEINFO=true && true
binutils/addr2line -e mips16_gprel_reloc_oob.bin 0
```
# Output
```
./addr2line: ../../fuzz/poc/mips16_gprel_reloc_oob.bin: invalid string offset
4294934328 >= 1447 for section `.strtab'
./addr2line: ../../fuzz/poc/mips16_gprel_reloc_oob.bin: invalid string offset
5153 >= 1447 for section `.strtab'
./addr2line: ../../fuzz/poc/mips16_gprel_reloc_oob.bin(.debug_info): relocation
27 has invalid symbol index 1701143909
./addr2line: BFD (GNU Binutils) 2.39.50.20221013 assertion fail
../../bfd/elf64-mips.c:4129
./addr2line: ../../fuzz/poc/mips16_gprel_reloc_oob.bin(.debug_info): relocation
28 has invalid symbol index 1701143909
./addr2line: BFD (GNU Binutils) 2.39.50.20221013 assertion fail
../../bfd/elf64-mips.c:4129
./addr2line: ../../fuzz/poc/mips16_gprel_reloc_oob.bin(.debug_info): relocation
29 has invalid symbol index 1701143909
./addr2line: BFD (GNU Binutils) 2.39.50.20221013 assertion fail
../../bfd/elf64-mips.c:4129
./addr2line: ../../fuzz/poc/mips16_gprel_reloc_oob.bin(.debug_info): relocation
30 has invalid symbol index 1701143909
./addr2line: BFD (GNU Binutils) 2.39.50.20221013 assertion fail
../../bfd/elf64-mips.c:4129
./addr2line: ../../fuzz/poc/mips16_gprel_reloc_oob.bin(.debug_info): relocation
31 has invalid symbol index 1701143909
./addr2line: BFD (GNU Binutils) 2.39.50.20221013 assertion fail
../../bfd/elf64-mips.c:4129
AddressSanitizer:DEADLYSIGNAL
=
==498292==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x5625a008350f
bp 0x7ffcbfba44b0 sp 0x7ffcbfba4490 T0)
==498292==The signal is caused by a READ memory access.
==498292==Hint: this fault was caused by a dereference of a high value address
(see register values below). Dissassemble the provided pc to learn which
register was used.
#0 0x5625a008350f in bfd_getl16 ../../bfd/libbfd.c:633
#1 0x5625a0464481 in _bfd_mips_elf_reloc_unshuffle
../../bfd/elfxx-mips.c:2359
#2 0x5625a04578d6 in mips16_gprel_reloc ../../bfd/elf64-mips.c:3665
#3 0x5625a0d7366c in bfd_perform_relocation ../../bfd/reloc.c:689
#4 0x5625a04b1b89 in _bfd_elf_mips_get_relocated_section_contents
../../bfd/elfxx-mips.c:13390
#5 0x5625a007664d in bfd_get_relocated_section_contents
../../bfd/bfd.c:2178
#6 0x5625a0d775c0 in bfd_simple_get_relocated_section_contents
../../bfd/simple.c:285
#7 0x5625a01c4eb1 in read_section ../../bfd/dwarf2.c:737
#8 0x5625a01dc1a0 in _bfd_dwarf2_slurp_debug_info ../../bfd/dwarf2.c:5487
#9 0x5625a01dd750 in _bfd_dwarf2_find_nearest_line_with_alt
../../bfd/dwarf2.c:5783
#10 0x5625a01dd47b in _bfd_dwarf2_find_nearest_line ../../bfd/dwarf2.c:5723
#11 0x5625a04b058e in _bfd_mips_elf_find_nearest_line
../../bfd/elfxx-mips.c:13070
#12 0x5625a006ab1e in find_address_in_section
../../binutils/addr2line.c:197
#13 0x5625a008c8b1 in bfd_map_over_sections ../../bfd/section.c:1373
#14 0x5625a006b8eb in translate_addresses ../../binutils/addr2line.c:337
#15 0x5625a006bfbc in process_file ../../binutils/addr2line.c:470
#16 0x5625a006c5b1 in main ../../binutils/addr2line.c:579
#17 0x7fc5aab14d8f in __libc_start_call_main
../sysdeps/nptl/libc_start_call_main.h:58
#18 0x7fc5aab14e3f in __libc_start_main_impl ../csu/libc-start.c:392
#19 0x5625a006a244 in _start
(/home/holing/pro/github/binutils-gdb/build/binutils/addr2line+0x33f244)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ../../bfd/libbfd.c:633 in bfd_getl16
==498292==ABORTING
Aborted
```
# Analysis
In function `mips_elf64_slurp_one_reloc_table`, `rela.r_offset` is filled with
content in the file[1][2], which can be controlled by attacker. Then
`rela.r_offset` is assigned to `relent->address`[3]. This value is then used to
calculate value of pointer `location`[4], and when this pointer is accessed
later[5], the crash occurs.
[1]
https://github.com/bminor/binutils-gdb/blob/1d4e62f498b1340569fd58c401f98c287cb5d071/bfd/elf64-mips.c#L4043
[2]
https://github.com/bminor