diff options
Diffstat (limited to 'lib/talloc')
-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; |