summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-02-01 10:26:05 +0100
committerAndreas Kling <kling@serenityos.org>2020-02-01 10:56:17 +0100
commit8d51352b967494d247391686c0df7876fee2a9dd (patch)
treeefa43fbe9450d3b644dd4f5690c04d1d98a49d86
parentf2846e8e08e03699399eb4262d34d5835552ce97 (diff)
downloadserenity-8d51352b967494d247391686c0df7876fee2a9dd.zip
Kernel: Add crash logging heuristic for uninitialized kmalloc()/kfree()
Since we scrub both kmalloc() and kfree() with predictable values, we can log a helpful message when hitting a crash that looks like it might be a dereference of such scrubbed data.
-rw-r--r--Kernel/Arch/i386/CPU.cpp6
-rw-r--r--Kernel/Heap/kmalloc.cpp4
-rw-r--r--Kernel/Heap/kmalloc.h3
3 files changed, 11 insertions, 2 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp
index d1ef90e6a4..52082ecc3d 100644
--- a/Kernel/Arch/i386/CPU.cpp
+++ b/Kernel/Arch/i386/CPU.cpp
@@ -317,10 +317,16 @@ void page_fault_handler(RegisterDump regs)
u32 malloc_scrub_pattern = explode_byte(MALLOC_SCRUB_BYTE);
u32 free_scrub_pattern = explode_byte(FREE_SCRUB_BYTE);
+ u32 kmalloc_scrub_pattern = explode_byte(KMALLOC_SCRUB_BYTE);
+ u32 kfree_scrub_pattern = explode_byte(KFREE_SCRUB_BYTE);
if ((fault_address & 0xffff0000) == (malloc_scrub_pattern & 0xffff0000)) {
kprintf("\033[33;1mNote: Address %p looks like it may be uninitialized malloc() memory\033[0m\n", fault_address);
} else if ((fault_address & 0xffff0000) == (free_scrub_pattern & 0xffff0000)) {
kprintf("\033[33;1mNote: Address %p looks like it may be recently free()'d memory\033[0m\n", fault_address);
+ } else if ((fault_address & 0xffff0000) == (kmalloc_scrub_pattern & 0xffff0000)) {
+ kprintf("\033[33;1mNote: Address %p looks like it may be uninitialized kmalloc() memory\033[0m\n", fault_address);
+ } else if ((fault_address & 0xffff0000) == (kfree_scrub_pattern & 0xffff0000)) {
+ kprintf("\033[33;1mNote: Address %p looks like it may be recently kfree()'d memory\033[0m\n", fault_address);
} else if (fault_address < 4096) {
kprintf("\033[33;1mNote: Address %p looks like a possible nullptr dereference\033[0m\n", fault_address);
}
diff --git a/Kernel/Heap/kmalloc.cpp b/Kernel/Heap/kmalloc.cpp
index 77bb72fee6..83f1348f5d 100644
--- a/Kernel/Heap/kmalloc.cpp
+++ b/Kernel/Heap/kmalloc.cpp
@@ -166,7 +166,7 @@ void* kmalloc_impl(size_t size)
sum_alloc += a->nchunk * CHUNK_SIZE;
sum_free -= a->nchunk * CHUNK_SIZE;
#ifdef SANITIZE_KMALLOC
- memset(ptr, 0xbb, (a->nchunk * CHUNK_SIZE) - sizeof(allocation_t));
+ memset(ptr, KMALLOC_SCRUB_BYTE, (a->nchunk * CHUNK_SIZE) - sizeof(allocation_t));
#endif
return ptr;
}
@@ -199,7 +199,7 @@ void kfree(void* ptr)
sum_free += a->nchunk * CHUNK_SIZE;
#ifdef SANITIZE_KMALLOC
- memset(a, 0xaa, a->nchunk * CHUNK_SIZE);
+ memset(a, KFREE_SCRUB_BYTE, a->nchunk * CHUNK_SIZE);
#endif
}
diff --git a/Kernel/Heap/kmalloc.h b/Kernel/Heap/kmalloc.h
index 772e54112d..a60422ea1e 100644
--- a/Kernel/Heap/kmalloc.h
+++ b/Kernel/Heap/kmalloc.h
@@ -30,6 +30,9 @@
//#define KMALLOC_DEBUG_LARGE_ALLOCATIONS
+#define KMALLOC_SCRUB_BYTE 0xbb
+#define KFREE_SCRUB_BYTE 0xaa
+
void kmalloc_init();
[[gnu::malloc, gnu::returns_nonnull, gnu::alloc_size(1)]] void* kmalloc_impl(size_t);
[[gnu::malloc, gnu::returns_nonnull, gnu::alloc_size(1)]] void* kmalloc_eternal(size_t);