diff options
author | Andreas Kling <kling@serenityos.org> | 2020-08-01 09:44:19 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-01 09:44:19 +0200 |
commit | 80eef2c0145f0abe97e6a3f3ab3263f88ebb7e7b (patch) | |
tree | 8c4e63ff996b9fce5f0764f44c836cc1e93daabd /DevTools/UserspaceEmulator/MallocTracer.cpp | |
parent | 030edbd513ce5b368fd5e6e665afe9f9051802cc (diff) | |
download | serenity-80eef2c0145f0abe97e6a3f3ab3263f88ebb7e7b.zip |
UserspaceEmulator: Report heap buffer overflows :^)
Diffstat (limited to 'DevTools/UserspaceEmulator/MallocTracer.cpp')
-rw-r--r-- | DevTools/UserspaceEmulator/MallocTracer.cpp | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/DevTools/UserspaceEmulator/MallocTracer.cpp b/DevTools/UserspaceEmulator/MallocTracer.cpp index 441632826e..cf3c78c071 100644 --- a/DevTools/UserspaceEmulator/MallocTracer.cpp +++ b/DevTools/UserspaceEmulator/MallocTracer.cpp @@ -96,6 +96,18 @@ MallocTracer::Mallocation* MallocTracer::find_mallocation(FlatPtr address) return nullptr; } +MallocTracer::Mallocation* MallocTracer::find_mallocation_before(FlatPtr address) +{ + Mallocation* found_mallocation = nullptr; + for (auto& mallocation : m_mallocations) { + if (mallocation.address >= address) + continue; + if (!found_mallocation || (mallocation.address > found_mallocation->address)) + found_mallocation = &mallocation; + } + return found_mallocation; +} + void MallocTracer::audit_read(FlatPtr address, size_t size) { if (!m_auditing_enabled) @@ -105,8 +117,18 @@ void MallocTracer::audit_read(FlatPtr address, size_t size) return; auto* mallocation = find_mallocation(address); - if (!mallocation) + + if (!mallocation) { + report("\n"); + report("==%d== \033[31;1mHeap buffer overflow\033[0m, invalid %zu-byte read at address %p\n", getpid(), size, address); + Emulator::the().dump_backtrace(); + if ((mallocation = find_mallocation_before(address))) { + size_t offset_into_mallocation = address - mallocation->address; + report("==%d== Address is %zu byte(s) after block of size %zu, allocated at:\n", getpid(), offset_into_mallocation - mallocation->size, mallocation->size); + Emulator::the().dump_backtrace(mallocation->malloc_backtrace); + } return; + } size_t offset_into_mallocation = address - mallocation->address; @@ -114,7 +136,7 @@ void MallocTracer::audit_read(FlatPtr address, size_t size) report("\n"); report("==%d== \033[31;1mUse-after-free\033[0m, invalid %zu-byte read at address %p\n", getpid(), size, address); Emulator::the().dump_backtrace(); - report("==%d== Address is %zu bytes into block of size %zu, allocated at:\n", getpid(), offset_into_mallocation, mallocation->size); + report("==%d== Address is %zu byte(s) into block of size %zu, allocated at:\n", getpid(), offset_into_mallocation, mallocation->size); Emulator::the().dump_backtrace(mallocation->malloc_backtrace); report("==%d== Later freed at:\n", getpid(), offset_into_mallocation, mallocation->size); Emulator::the().dump_backtrace(mallocation->free_backtrace); @@ -131,8 +153,17 @@ void MallocTracer::audit_write(FlatPtr address, size_t size) return; auto* mallocation = find_mallocation(address); - if (!mallocation) + if (!mallocation) { + report("\n"); + report("==%d== \033[31;1mHeap buffer overflow\033[0m, invalid %zu-byte write at address %p\n", getpid(), size, address); + Emulator::the().dump_backtrace(); + if ((mallocation = find_mallocation_before(address))) { + size_t offset_into_mallocation = address - mallocation->address; + report("==%d== Address is %zu byte(s) after block of size %zu, allocated at:\n", getpid(), offset_into_mallocation - mallocation->size, mallocation->size); + Emulator::the().dump_backtrace(mallocation->malloc_backtrace); + } return; + } size_t offset_into_mallocation = address - mallocation->address; @@ -140,7 +171,7 @@ void MallocTracer::audit_write(FlatPtr address, size_t size) report("\n"); report("==%d== \033[31;1mUse-after-free\033[0m, invalid %zu-byte write at address %p\n", getpid(), size, address); Emulator::the().dump_backtrace(); - report("==%d== Address is %zu bytes into block of size %zu, allocated at:\n", getpid(), offset_into_mallocation, mallocation->size); + report("==%d== Address is %zu byte(s) into block of size %zu, allocated at:\n", getpid(), offset_into_mallocation, mallocation->size); Emulator::the().dump_backtrace(mallocation->malloc_backtrace); report("==%d== Later freed at:\n", getpid(), offset_into_mallocation, mallocation->size); Emulator::the().dump_backtrace(mallocation->free_backtrace); |