summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_malloc.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-01-31 11:09:21 +0000
committerpjd <pjd@FreeBSD.org>2006-01-31 11:09:21 +0000
commit645dd7b662b95a91b935a1b4b9d354770a873a8d (patch)
tree5578d06f9b3e97650d2847a2198d21f29bb26546 /sys/kern/kern_malloc.c
parent8920c8cd7449851a87b664de80046b23913acd5e (diff)
downloadFreeBSD-src-645dd7b662b95a91b935a1b4b9d354770a873a8d.zip
FreeBSD-src-645dd7b662b95a91b935a1b4b9d354770a873a8d.tar.gz
Add buffer corruption protection (RedZone) for kernel's malloc(9).
It detects both: buffer underflows and buffer overflows bugs at runtime (on free(9) and realloc(9)) and prints backtraces from where memory was allocated and from where it was freed. Tested by: kris
Diffstat (limited to 'sys/kern/kern_malloc.c')
-rw-r--r--sys/kern/kern_malloc.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 6b2e73d..27c2d19 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -65,6 +65,9 @@ __FBSDID("$FreeBSD$");
#ifdef DEBUG_MEMGUARD
#include <vm/memguard.h>
#endif
+#ifdef DEBUG_REDZONE
+#include <vm/redzone.h>
+#endif
#if defined(INVARIANTS) && defined(__i386__)
#include <machine/cpu.h>
@@ -259,7 +262,7 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
caddr_t va;
uma_zone_t zone;
uma_keg_t keg;
-#ifdef DIAGNOSTIC
+#if defined(DIAGNOSTIC) || defined(DEBUG_REDZONE)
unsigned long osize = size;
#endif
@@ -302,6 +305,10 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
return memguard_alloc(size, flags);
#endif
+#ifdef DEBUG_REDZONE
+ size = redzone_size_ntor(size);
+#endif
+
if (size <= KMEM_ZMAX) {
if (size & KMEM_ZMASK)
size = (size & ~KMEM_ZMASK) + KMEM_ZBASE;
@@ -331,6 +338,10 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
memset(va, 0x70, osize);
}
#endif
+#ifdef DEBUG_REDZONE
+ if (va != NULL)
+ va = redzone_setup(va, osize);
+#endif
return ((void *) va);
}
@@ -358,6 +369,11 @@ free(void *addr, struct malloc_type *mtp)
}
#endif
+#ifdef DEBUG_REDZONE
+ redzone_check(addr);
+ addr = redzone_addr_ntor(addr);
+#endif
+
size = 0;
slab = vtoslab((vm_offset_t)addr & (~UMA_SLAB_MASK));
@@ -421,6 +437,10 @@ if (memguard_cmp(mtp)) {
} else {
#endif
+#ifdef DEBUG_REDZONE
+ slab = NULL;
+ alloc = redzone_get_size(addr);
+#else
slab = vtoslab((vm_offset_t)addr & ~(UMA_SLAB_MASK));
/* Sanity check */
@@ -437,6 +457,7 @@ if (memguard_cmp(mtp)) {
if (size <= alloc
&& (size > (alloc >> REALLOC_FRACTION) || alloc == MINALLOCSIZE))
return (addr);
+#endif /* !DEBUG_REDZONE */
#ifdef DEBUG_MEMGUARD
}
OpenPOWER on IntegriCloud