From e974f98eb4171b50a005084deb15dd519c8fbb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Wed, 1 Nov 2023 18:04:07 +0100 Subject: [PATCH] Improve stability of the jemalloc workaround When jemalloc is linked into BIND 9 binaries (rather than preloaded or used as the system allocator), depending on the decisions made by the linker, the malloc() symbol may be resolved to a non-jemalloc implementation at runtime. Such a scenario foils the workaround added in commit 2da371d005c472dea349110e3ef9a6ed7b18b824 as it relies on the jemalloc implementation of malloc() to be executed. Handle the above scenario properly by calling mallocx() explicitly instead of relying on the runtime resolution of the malloc() symbol. Use trivial wrapper functions to avoid the need to copy multiple #ifdef lines from lib/isc/mem.c to lib/isc/trampoline.c. Using a simpler alternative, e.g. calling isc_mem_create() & isc_mem_destroy(), was already considered before and rejected, as described in the log message for commit 2da371d005c472dea349110e3ef9a6ed7b18b824. ADJUST_ZERO_ALLOCATION_SIZE() is only used in isc__mem_free_noctx() to concisely avoid compilation warnings about its 'size' parameter not being used when building against jemalloc < 4.0.0 (as sdallocx() is then redefined to dallocx(), which has a different signature). --- lib/isc/mem.c | 11 +++++++++++ lib/isc/mem_p.h | 11 +++++++++++ lib/isc/trampoline.c | 5 +++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 61a66f6087..6560833752 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -1906,3 +1906,14 @@ isc__mem_printactive(isc_mem_t *ctx, FILE *file) { UNUSED(file); #endif /* if ISC_MEM_TRACKLINES */ } + +void * +isc__mem_alloc_noctx(size_t size) { + return mallocx(size, 0); +} + +void +isc__mem_free_noctx(void *ptr, size_t size) { + ADJUST_ZERO_ALLOCATION_SIZE(size); + sdallocx(ptr, size, 0); +} diff --git a/lib/isc/mem_p.h b/lib/isc/mem_p.h index 611a025a14..d95bfc3f06 100644 --- a/lib/isc/mem_p.h +++ b/lib/isc/mem_p.h @@ -26,6 +26,17 @@ isc__mem_printactive(isc_mem_t *mctx, FILE *file); * a single memory context. */ +void * +isc__mem_alloc_noctx(size_t size); +void +isc__mem_free_noctx(void *ptr, size_t size); +/*%< + * Allocate memory that is not associated with an isc_mem memory context. + * + * For use purely in the isc_trampoline unit, to avoid the need of copying + * multiple #ifdef lines from lib/isc/mem.c to lib/isc/trampoline.c. + */ + void isc__mem_checkdestroyed(void); diff --git a/lib/isc/trampoline.c b/lib/isc/trampoline.c index 58171d9138..3e58fa7032 100644 --- a/lib/isc/trampoline.c +++ b/lib/isc/trampoline.c @@ -22,6 +22,7 @@ #include #include +#include "mem_p.h" #include "trampoline_p.h" #define ISC__TRAMPOLINE_UNUSED 0 @@ -148,7 +149,7 @@ isc__trampoline_detach(isc__trampoline_t *trampoline) { isc__trampoline_min = trampoline->tid; } - free(trampoline->jemalloc_enforce_init); + isc__mem_free_noctx(trampoline->jemalloc_enforce_init, 8); free(trampoline); uv_mutex_unlock(&isc__trampoline_lock); @@ -174,7 +175,7 @@ isc__trampoline_attach(isc__trampoline_t *trampoline) { * so that an optimizing compiler does not strip away such a pair of * malloc() + free() calls altogether, as it would foil the fix. */ - trampoline->jemalloc_enforce_init = malloc(8); + trampoline->jemalloc_enforce_init = isc__mem_alloc_noctx(8); uv_mutex_unlock(&isc__trampoline_lock); }