Resetting section vma after _bfd_dwarf2_find_nearest_line
authorAlan Modra <amodra@gmail.com>
Sat, 4 Feb 2023 00:59:05 +0000 (11:29 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 6 Feb 2023 00:01:26 +0000 (10:31 +1030)
commitd4a8b80189c3fdb9d041583e576315a7306a2279
treefdf57f35646ffde23a2b91a3c9990400a3c7fb03
parent023b960d59c25994da233ea371deb26105fbacc8
Resetting section vma after _bfd_dwarf2_find_nearest_line

There are failure paths in _bfd_dwarf2_slurp_debug_info that can
result in altered section vmas.  Also, when setting ET_REL section
vmas it's not too difficult to handle cases where the original vma was
non-zero, so do that too.

This patch was really in response to an addr2line buffer overflow
processing a fuzzed mips relocatable object file.  The file had a
number of .debug_info sections with relocations that included lo16 and
hi16 relocs, and in that order.  At least one section VMA was
non-zero.  This resulted in processing of DWARF info twice, once via
the call to _bfd_dwarf2_find_nearest_line in
_bfd_mips_elf_find_nearest_line, and because that failed leaving VMAs
altered, the second via the call in _bfd_elf_find_nearest_line.  The
first call left entries on mips_hi16_list pointing at buffers
allocated during the first call, the second call processed the
mips_hi16_list after the buffers had been freed.  (At least when
running with asan and under valgrind.  Under gdb with a non-asan
addr2line the second call allocated exactly the same buffer and the
bug didn't show.)  Now I don't really care too much what happens with
fuzzed files, but the logic in _bfd_dwarf2_find_nearest_line is meant
to result in only one read of .debug_info, not multiple reads of the
same info when there are errors.  This patch fixes that problem.

* dwarf2.c (struct adjusted_section): Add orig_vma.
(unset_sections): Reset vma to it.
(place_sections): Handle non-zero vma too.  Save orig_vma.
(_bfd_dwarf2_slurp_debug_info): Tidy.  Correct outdated comment.
On error returns after calling place_sections, call
unset_sections.
(_bfd_dwarf2_find_nearest_line_with_alt): Simplify call to
unset_sections.
bfd/dwarf2.c