summaryrefslogtreecommitdiff
path: root/DevTools/UserspaceEmulator/MallocTracer.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-08-01 09:44:19 +0200
committerAndreas Kling <kling@serenityos.org>2020-08-01 09:44:19 +0200
commit80eef2c0145f0abe97e6a3f3ab3263f88ebb7e7b (patch)
tree8c4e63ff996b9fce5f0764f44c836cc1e93daabd /DevTools/UserspaceEmulator/MallocTracer.cpp
parent030edbd513ce5b368fd5e6e665afe9f9051802cc (diff)
downloadserenity-80eef2c0145f0abe97e6a3f3ab3263f88ebb7e7b.zip
UserspaceEmulator: Report heap buffer overflows :^)
Diffstat (limited to 'DevTools/UserspaceEmulator/MallocTracer.cpp')
-rw-r--r--DevTools/UserspaceEmulator/MallocTracer.cpp39
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);