gdb: Handle malformed ELF, symbols in non-allocatable sections
authorAndrew Burgess <andrew.burgess@embecosm.com>
Fri, 6 Dec 2019 23:12:29 +0000 (23:12 +0000)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Mon, 13 Jan 2020 23:57:42 +0000 (23:57 +0000)
commit44e4c7757a733949d511d97a7d95db913f423f1b
treed56563338f8435b7173b4675f6bf1075f78acd41
parentd93c6db74b7a9d6154f55f92d96f38819838bc99
gdb: Handle malformed ELF, symbols in non-allocatable sections

I ended up debugging a malformed ELF where a section containing
executable code was not correctly marked as allocatable.  Before
realising the ELF was corrupted I tried to place a breakpoint on a
symbol in the non-allocatable, executable section, and GDB crashed.

Though trying to debug such an ELF clearly isn't going to go well I
would prefer, as far as possible, that any input, no matter how
corrupted, not crash GDB.

The crash occurs when trying to set a breakpoint on the name of a
function from the corrupted section.  GDB converts the symbol to a
symtab_and_line, and looks up a suitable section for this.

The problem is that the section is actually an obj_section, which is
stored in the table within the objfile, and we only initialise this
table for allocatable sections (see add_to_objfile_sections_full in
objfiles.c).  So, if the symbol is in a non-allocatable section then
we end up referencing an uninitialised obj_section.

Later we call get_sal_arch on the symtab_and_line, which calls
get_objfile_arch, which uses the objfile from the uninitialised
obj_section, which will be nullptr, at which point GDB crashes.

The fix I propose here is that when we setup the section references on
msymbols, we should check if the bfd_section being referenced is
allocatable or not.  If it is not then we should set the section
reference back to the default 0 section (see how MSYMBOL_OBJ_SECTION
and SYMBOL_OBJ_SECTION treat the 0 section index).

With this fix in place GDB no longer crashes.  Instead GDB creates the
breakpoint at the non-allocated address, and then fails, with an
error, when it tries to insert the breakpoint.

gdb/ChangeLog:

* elfread.c (record_minimal_symbol): Set section index to 0 for
non-allocatable sections.

gdb/testsuite/ChangeLog:

* gdb.dwarf2/dw2-bad-elf-other.S: New file.
* gdb.dwarf2/dw2-bad-elf.c: New file.
* gdb.dwarf2/dw2-bad-elf.exp: New file.

Change-Id: Ie05436ab4c6a71440304d20ee639dfb021223f8b
gdb/ChangeLog
gdb/elfread.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.dwarf2/dw2-bad-elf-other.S [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/dw2-bad-elf.c [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp [new file with mode: 0644]