diff options
author | pjd <pjd@FreeBSD.org> | 2006-01-31 11:09:21 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-01-31 11:09:21 +0000 |
commit | 645dd7b662b95a91b935a1b4b9d354770a873a8d (patch) | |
tree | 5578d06f9b3e97650d2847a2198d21f29bb26546 /sys/kern/kern_malloc.c | |
parent | 8920c8cd7449851a87b664de80046b23913acd5e (diff) | |
download | FreeBSD-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.c | 23 |
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 } |