mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 06:58:11 +00:00
UserspaceEmulator: Catch use-after-frees by tracking malloc/free :^)
This patch introduces a "MallocTracer" to the UserspaceEmulator. If this object is present on the Emulator, it can be notified whenever the emulated program does a malloc() or free(). The notifications come in via a magic instruction sequence that we embed in the LibC malloc() and free() functions. The sequence is: "salc x2, push reg32 x2, pop reg32 x3" The data about the malloc/free operation is in the three pushes. We make sure the sequence is harmless when running natively. Memory accesses on MmapRegion are then audited to see if they fall inside a known-to-be-freed malloc chunk. If so, we complain loud and red in the debugger output. :^) This is very, very cool! :^) It's also a whole lot slower than before, since now we're auditing memory accesses against a new set of metadata. This will need to be optimized (and running in this mode should be opt-in, perhaps even a separate program, etc.)
This commit is contained in:
parent
d7c87e84f3
commit
c314292319
9 changed files with 274 additions and 5 deletions
|
@ -66,6 +66,7 @@ Emulator::Emulator(const Vector<String>& arguments, NonnullRefPtr<ELF::Loader> e
|
|||
: m_elf(move(elf))
|
||||
, m_cpu(*this)
|
||||
{
|
||||
m_malloc_tracer = make<MallocTracer>();
|
||||
ASSERT(!s_the);
|
||||
s_the = this;
|
||||
setup_stack(arguments);
|
||||
|
@ -167,12 +168,20 @@ int Emulator::exec()
|
|||
return m_exit_status;
|
||||
}
|
||||
|
||||
bool Emulator::is_in_malloc_or_free() const
|
||||
{
|
||||
auto symbol = m_elf->symbolicate(m_cpu.eip());
|
||||
return symbol.starts_with("malloc") || symbol.starts_with("free");
|
||||
}
|
||||
|
||||
static pid_t s_pid = getpid();
|
||||
|
||||
void Emulator::dump_backtrace()
|
||||
{
|
||||
u32 offset = 0;
|
||||
String symbol = m_elf->symbolicate(m_cpu.eip(), &offset);
|
||||
|
||||
printf("> %#08x %s +%#x\n", m_cpu.eip(), symbol.characters(), offset);
|
||||
dbgprintf("==%d== %#08x %s +%#x\n", s_pid, m_cpu.eip(), symbol.characters(), offset);
|
||||
|
||||
u32 frame_ptr = m_cpu.ebp();
|
||||
while (frame_ptr) {
|
||||
|
@ -181,7 +190,7 @@ void Emulator::dump_backtrace()
|
|||
return;
|
||||
symbol = m_elf->symbolicate(ret_ptr, &offset);
|
||||
if (!symbol.is_null())
|
||||
printf("> %#08x %s +%#x\n", ret_ptr, symbol.characters(), offset);
|
||||
dbgprintf("==%d== %#08x %s +%#x\n", s_pid, ret_ptr, symbol.characters(), offset);
|
||||
|
||||
frame_ptr = m_mmu.read32({ 0x20, frame_ptr });
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue