diff options
author | jeff <jeff@FreeBSD.org> | 2002-05-02 09:07:04 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2002-05-02 09:07:04 +0000 |
commit | 6bfc4bdd9687d28dcbb4ee25d5de86b01147a23d (patch) | |
tree | d04d4200ce8e73582726b459fe3a5978841495d0 /sys/vm | |
parent | fb737bd04bbaa01e816c020910e4eb4f70ab02bb (diff) | |
download | FreeBSD-src-6bfc4bdd9687d28dcbb4ee25d5de86b01147a23d.zip FreeBSD-src-6bfc4bdd9687d28dcbb4ee25d5de86b01147a23d.tar.gz |
Hide a pointer to the malloc_type bucket at the end of the freed memory. If
this memory is modified after it has been freed we can now report it's
previous owner.
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/uma_dbg.c | 79 | ||||
-rw-r--r-- | sys/vm/uma_dbg.h | 7 |
2 files changed, 84 insertions, 2 deletions
diff --git a/sys/vm/uma_dbg.c b/sys/vm/uma_dbg.c index 0e71c6c..ab7e1b8 100644 --- a/sys/vm/uma_dbg.c +++ b/sys/vm/uma_dbg.c @@ -40,6 +40,7 @@ #include <sys/queue.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/malloc.h> #include <machine/types.h> @@ -111,6 +112,82 @@ trash_fini(void *mem, int size) trash_ctor(mem, size, NULL); } +/* + * Checks an item to make sure it hasn't been overwritten since freed. + * + * Complies with standard ctor arg/return + * + */ +void +mtrash_ctor(void *mem, int size, void *arg) +{ + struct malloc_type **ksp; + u_int32_t *p = mem; + int cnt; + + size -= sizeof(struct malloc_type *); + ksp = (struct malloc_type **)mem; + ksp += size / sizeof(struct malloc_type *); + cnt = size / sizeof(uma_junk); + + for (p = mem; cnt > 0; cnt--, p++) + if (*p != uma_junk) { + printf("Memory modified after free %p(%d)\n", + mem, size); + panic("Most recently used by %s\n", (*ksp == NULL)? + "none" : (*ksp)->ks_shortdesc); + } +} + +/* + * Fills an item with predictable garbage + * + * Complies with standard dtor arg/return + * + */ +void +mtrash_dtor(void *mem, int size, void *arg) +{ + int cnt; + u_int32_t *p; + + size -= sizeof(struct malloc_type *); + cnt = size / sizeof(uma_junk); + + for (p = mem; cnt > 0; cnt--, p++) + *p = uma_junk; +} + +/* + * Fills an item with predictable garbage + * + * Complies with standard init arg/return + * + */ +void +mtrash_init(void *mem, int size) +{ + struct malloc_type **ksp; + + mtrash_dtor(mem, size, NULL); + + ksp = (struct malloc_type **)mem; + ksp += (size / sizeof(struct malloc_type *)) - 1; + *ksp = NULL; +} + +/* + * Checks an item to make sure it hasn't been overwritten since it was freed. + * + * Complies with standard fini arg/return + * + */ +void +mtrash_fini(void *mem, int size) +{ + mtrash_ctor(mem, size, NULL); +} + static uma_slab_t uma_dbg_getslab(uma_zone_t zone, void *item) { @@ -170,8 +247,6 @@ uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item) { int freei; - return; - if (slab == NULL) { slab = uma_dbg_getslab(zone, item); if (slab == NULL) diff --git a/sys/vm/uma_dbg.h b/sys/vm/uma_dbg.h index fed04a6..7967a44 100644 --- a/sys/vm/uma_dbg.h +++ b/sys/vm/uma_dbg.h @@ -43,6 +43,13 @@ void trash_ctor(void *mem, int size, void *arg); void trash_dtor(void *mem, int size, void *arg); void trash_init(void *mem, int size); void trash_fini(void *mem, int size); + +/* For use only by malloc */ +void mtrash_ctor(void *mem, int size, void *arg); +void mtrash_dtor(void *mem, int size, void *arg); +void mtrash_init(void *mem, int size); +void mtrash_fini(void *mem, int size); + void uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item); void uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item); |