From 29585309bf479fe73c3be59e2f8371c3b6c4554a Mon Sep 17 00:00:00 2001 From: Tomas Kuthan Date: Mon, 7 Aug 2017 16:01:43 +0200 Subject: [PATCH] Fix memleak in libverto:vfree verto_set_allocator(resize, hierarchical) has an unducumented requirement on allocator function resize, that resize(ptr, 0) is equivalent to free(ptr). Some implementations of the default allocator realloc don't meet this requirement. realloc(ptr, 0) may return a unique pointer that can be successfully passed to free. This new pointer never gets freed and the memory overhead leaks. This fix replaces realloc(ptr, 0) with free(ptr) in vresize and documents the allocator requirement. [rharwood@redhat.com: Cleanup comments slightly] Closes: #18 (cherry picked from commit 968d542e83619de9759ac4d8f13df30e1016b6c2) --- src/verto.c | 5 +++++ src/verto.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/verto.c b/src/verto.c index b98142d..da2ebc5 100644 --- a/src/verto.c +++ b/src/verto.c @@ -132,6 +132,11 @@ vresize(void *mem, size_t size) { if (!resize_cb) resize_cb = &realloc; + if (size == 0 && resize_cb == &realloc) { + /* Avoid memleak as realloc(X, 0) can return a free-able pointer. */ + free(mem); + return NULL; + } return (*resize_cb)(mem, size); } diff --git a/src/verto.h b/src/verto.h index 15fd81e..8000d2d 100644 --- a/src/verto.h +++ b/src/verto.h @@ -196,7 +196,8 @@ verto_set_default(const char *impl, verto_ev_type reqtypes); * @see verto_add_idle() * @see verto_add_signal() * @see verto_add_child() - * @param resize The allocator to use (behaves like realloc()) + * @param resize The allocator to use (behaves like realloc(); + * resize(ptr, 0) must free memory at ptr.) * @param hierarchical Zero if the allocator is not hierarchical */ int