ELFCore: Read register notes in the namespace that names them - #734
ELFCore: Read register notes in the namespace that names them#734zardus wants to merge 2 commits into
Conversation
ELF note types are namespaced by the note name: type 1 is a Linux struct elf_prstatus only inside the CORE namespace that Linux uses. ELFCore decoded every NT_PRSTATUS with the Linux layout regardless, so a FreeBSD core raised struct.error when its shorter descriptor ran out, and a NetBSD one was read as a register block when it actually holds a struct netbsd_elfcore_procinfo, which carries no registers at all - those live in a per-LWP note typed with the number of the PT_GETREGS ptrace request. Cores whose process ABI is not the one their ELF header implies, an x32 process dumped by an x86-64 kernel for instance, tripped an assert that python -O strips, leaving registers read at the wrong stride behind. Dispatch on the note name, read FreeBSD struct prstatus and NetBSD per-LWP register notes, and check each descriptor against the layout it is about to be read with. Linux writes the GDT entry note under LINUX rather than under CORE, so look for it there. A thread whose registers cannot be decoded is now dropped with a warning instead of taking the whole load down with it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Validation record for head
The tests load core dumps written by the kernels they name, added as fixtures by angr/binaries#176; the checks on this PR stay red until that merges, because CI checks out
Seven of those nine are the fixtures the tests now load, as Every Linux x86 cores are unaffected. Fourteen of them, including thread_crash/linux-i386.core ( Caveats:
|
|
Corpus decompilation diffs can be found at angr/dec-snapshots@master...angr/cle_734 |
The regression tests for note dispatch built their own core files with struct.pack. A hand-assembled core only ever has the shape the test author believed the kernel writes, so it can pass while a real FreeBSD, NetBSD or x32 core still fails to load. Load core dumps written by each of those kernels instead, and assert on the register values the dumped process actually held.
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
ELF note types are namespaced by the note's name, but
ELFCoredecoded everyNT_PRSTATUSas a Linuxstruct elf_prstatus: a FreeBSD core raisedstruct.errorwhen its shorter descriptor ran out, and a NetBSD one was read as registers though its type-1 note is astruct netbsd_elfcore_procinfothat holds none. Only an assert, whichpython -Ostrips, caught a length mismatch.ELFCorenow dispatches on the note name, reads FreeBSD'sstruct prstatusand NetBSD's per-LWP register note, and checks each descriptor against the layout it is about to be read with. Linux namespaces its GDT entry noteLINUXrather thanCORE, so that one is read there. A thread whose registers will not decode is dropped with a warning instead of failing the load.The regression test loads core dumps written by each of those kernels, added as fixtures by angr/binaries#176, so the checks here stay red until that merges: CI checks out
binariesmaster.Validation: #734 (comment)