diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-11-19 11:04:33 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-11-19 15:17:42 +1100 |
commit | 999f3ed2ce656ecf97b95afa85823115939f9360 (patch) | |
tree | 3f131913280332b7ee8be0538a84548f39f26684 | |
parent | 58c43f74b9bc2d660f58ccfe912bd3fff7cf672e (diff) | |
download | samba-999f3ed2ce656ecf97b95afa85823115939f9360.tar.gz samba-999f3ed2ce656ecf97b95afa85823115939f9360.tar.bz2 samba-999f3ed2ce656ecf97b95afa85823115939f9360.zip |
talloc: added TALLOC_FREE_FILL environment variable
when this environment variable is set, talloc will fill freed memory
with the value from that environment variable. This can be used to
help find use after free bugs when valgrind is too slow to be used
-rw-r--r-- | lib/talloc/talloc.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c index 84947a77b0..ec67a463ab 100644 --- a/lib/talloc/talloc.c +++ b/lib/talloc/talloc.c @@ -104,6 +104,17 @@ static void *null_context; static void *autofree_context; +/* used to enable fill of memory on free, which can be useful for + * catching use after free errors when valgrind is too slow + */ +static struct { + bool initialised; + bool enabled; + uint8_t fill_value; +} talloc_fill; + +#define TALLOC_FILL_ENV "TALLOC_FREE_FILL" + struct talloc_reference_handle { struct talloc_reference_handle *next, *prev; void *ptr; @@ -567,6 +578,16 @@ static inline int _talloc_free_internal(void *ptr, const char *location) return -1; } + /* possibly initialised the talloc fill value */ + if (!talloc_fill.initialised) { + const char *fill = getenv(TALLOC_FILL_ENV); + if (fill != NULL) { + talloc_fill.enabled = true; + talloc_fill.fill_value = strtoul(fill, NULL, 0); + } + talloc_fill.initialised = true; + } + tc = talloc_chunk_from_ptr(ptr); if (unlikely(tc->refs)) { @@ -662,10 +683,19 @@ static inline int _talloc_free_internal(void *ptr, const char *location) *pool_object_count -= 1; if (*pool_object_count == 0) { + if (talloc_fill.enabled) { + memset(TC_PTR_FROM_CHUNK(pool), talloc_fill.fill_value, pool->size); + } free(pool); } } else { + if (talloc_fill.enabled) { + /* don't wipe the header, to allow the + double-free logic to still work + */ + memset(TC_PTR_FROM_CHUNK(tc), talloc_fill.fill_value, tc->size); + } free(tc); } return 0; |