Fix vmmap coredump test (#1391)

* fix shlint

* Fix crash when unable to get ehdr and fix vmmap coredump test

This commit fixes two issues and test them.

1. It changes the reads in `get_ehdr` to partial reads so that inability
   to read the `vmmap.start` address there will not crash Pwndbg with
`gdb.error` but instead we will simply return `None` as expected from
this function. This crash could happen on Debian 10 (GDB 8.2.1) and
Ubuntu 18.04 (not sure which GDB) when you did:
- gdb ./binary-that-crashes
- `run`
- `generate-core-file /tmp/core`
- `file` - to unload the binary
- `core-file /tmp/core` - to load the generated core

At this point I think we may have preserved the old vmmap info and use
it in `get_ehdr` maybe, which then crashed? I am not sure, but this fix
here works.

To test this behavior properly I also added the `unload_file`
parametrization to the
`test_command_vmmap_on_coredump_on_crash_simple_binary` test.

2. We fix the vmmap coredump test case when the `info proc mappings` returns nothing on core
   dumps on old GDBs. In such case we are missing the vmmap info about
the binary mapping, so now we properly remove it in the test.
This commit is contained in:
Disconnect3d 2022-11-23 03:15:39 +07:00 committed by GitHub
parent 117e69f842
commit c6ab8dc671
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 6 deletions

View File

@ -249,7 +249,7 @@ def get_ehdr(pointer):
return None, None
# We first check if the beginning of the page contains the ELF magic
if pwndbg.gdblib.memory.read(vmmap.start, 4) == b"\x7fELF":
if pwndbg.gdblib.memory.read(vmmap.start, 4, partial=True) == b"\x7fELF":
base = vmmap.start
# The page did not have ELF magic; it may be that .text and binary start are split
@ -260,7 +260,7 @@ def get_ehdr(pointer):
vmmap = v
break
if pwndbg.gdblib.memory.read(vmmap.start, 4) == b"\x7fELF":
if pwndbg.gdblib.memory.read(vmmap.start, 4, partial=True) == b"\x7fELF":
base = vmmap.start
if base is None:

View File

@ -92,7 +92,7 @@ install_apt() {
build-essential \
gdb \
parallel \
netcat-openbsd
netcat-openbsd
if [[ "$1" == "22.04" ]]; then
sudo apt install shfmt
@ -107,7 +107,7 @@ install_pacman() {
set_zigpath "$(pwd)/.zig"
# add debug repo for glibc-debug
cat <<EOF | sudo tee -a /etc/pacman.conf
cat << EOF | sudo tee -a /etc/pacman.conf
[core-debug]
Include = /etc/pacman.d/mirrorlist

View File

@ -1,6 +1,7 @@
import tempfile
import gdb
import pytest
import pwndbg
import tests
@ -40,7 +41,8 @@ def get_proc_maps():
return maps
def test_command_vmmap_on_coredump_on_crash_simple_binary(start_binary):
@pytest.mark.parametrize("unload_file", (False, True))
def test_command_vmmap_on_coredump_on_crash_simple_binary(start_binary, unload_file):
"""
Example vmmap when debugging binary:
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
@ -84,6 +86,10 @@ def test_command_vmmap_on_coredump_on_crash_simple_binary(start_binary):
core = tempfile.mktemp()
gdb.execute("generate-core-file %s" % core)
# The test should work fine even if we unload the original binary
if unload_file:
gdb.execute("file")
#### TEST COREDUMP VMMAP
# Now, let's load the generated core file
gdb.execute("core-file %s" % core)
@ -94,7 +100,18 @@ def test_command_vmmap_on_coredump_on_crash_simple_binary(start_binary):
# Note: we will now see one less vmmap page as [vvar] will be missing
assert vmmaps[0] == "LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA"
vmmaps = [i.split() for i in vmmaps[2:]]
assert len(vmmaps) == old_len_vmmaps - 1
has_proc_maps = "warning: unable to find mappings in core file" not in gdb.execute(
"info proc mappings", to_string=True
)
if has_proc_maps:
assert len(vmmaps) == old_len_vmmaps - 1
else:
# E.g. on Debian 10 with GDB 8.2.1 the core dump does not contain mappings info
assert len(vmmaps) == old_len_vmmaps - 2
binary_map = next(i for i in expected_maps if CRASH_SIMPLE_BINARY in i[-1])
expected_maps.remove(binary_map)
# Fix up expected maps
next(i for i in expected_maps if i[-1] == "[vdso]")[-1] = "load2"