From 22586524e32f14c44239063088a38ccea8abc9b7 Mon Sep 17 00:00:00 2001 From: Tim Duesterhus Date: Fri, 8 Jan 2021 10:35:33 +0100 Subject: [PATCH] BUG/MINOR: hlua: Fix memory leak in hlua_alloc During a configuration check valgrind reports: ==14425== 0 bytes in 106 blocks are definitely lost in loss record 1 of 107 ==14425== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14425== by 0x4C2FDEF: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14425== by 0x443CFC: hlua_alloc (hlua.c:8662) ==14425== by 0x5F72B11: luaM_realloc_ (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0) ==14425== by 0x5F78089: luaH_free (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0) ==14425== by 0x5F707D3: sweeplist (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0) ==14425== by 0x5F710D0: luaC_freeallobjects (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0) ==14425== by 0x5F7715D: close_state (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0) ==14425== by 0x443D4C: hlua_deinit (hlua.c:9302) ==14425== by 0x543F88: deinit (haproxy.c:2742) ==14425== by 0x5448E7: deinit_and_exit (haproxy.c:2830) ==14425== by 0x5455D9: init (haproxy.c:2044) This is due to Lua calling `hlua_alloc()` with `ptr = NULL` and `nsize = 0`. While `realloc` is supposed to be equivalent `free()` if the size is `0` this is only required for a non-NULL pointer. Apparently my allocator (or valgrind) actually allocates a zero size area if the pointer is NULL, possibly taking up some memory for management structures. Fix this leak by specifically handling the case where both the pointer and the size are `0`. This bug appears to have been introduced with the introduction of the multi-threaded Lua, thus this fix is specific for 2.4. No backport needed. --- src/hlua.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hlua.c b/src/hlua.c index a52a1b50d..8ad9e9f4a 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -8640,6 +8640,9 @@ static void *hlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) struct hlua_mem_allocator *zone = ud; size_t limit, old, new; + if (unlikely(!ptr && !nsize)) + return NULL; + /* a limit of ~0 means unlimited and boot complete, so there's no need * for accounting anymore. */