summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/talloc/talloc.c30
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;