From b8e71f95802f486b2fcf35437a96915177a2892a Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Fri, 3 Feb 2023 12:29:00 +0000 Subject: [PATCH] Fix ISC_MEM_ZERO on allocators with malloc_usable_size() ISC_MEM_ZERO requires great care to use when the space returned by the allocator is larger than the requested space, and when memory is reallocated. You must ensure that _every_ call to allocate or reallocate a particular block of memory uses ISC_MEM_ZERO, to ensure that the extra space is zeroed as expected. (When ISC_MEMFLAG_FILL is set, the extra space will definitely be non-zero.) When BIND is built without jemalloc, ISC_MEM_ZERO is implemented in `jemalloc_shim.h`. This had a bug on systems that have malloc_size() or malloc_usable_size(): memory was only zeroed up to the requested size, not the allocated size. When an oversized allocation was returned, and subsequently reallocated larger, memory between the original requested size and the original allocated size could contain unexpected nonzero junk. The realloc call does not know the original requested size and only zeroes from the original allocated size onwards. After this change, `jemalloc_shim.h` always zeroes up to the allocated size, not the requested size. --- CHANGES | 3 +++ lib/isc/jemalloc_shim.h | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 18820e0b47..748fe8afb5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +6084. [bug] When BIND was built without jemalloc, the allocator flag + ISC_MEM_ZERO could return non-zero memory. [GL #3845] + 6083. [bug] Fix DNSRPS-enabled builds as they were inadvertently broken by changes 5949 and 6042. [GL #3827] diff --git a/lib/isc/jemalloc_shim.h b/lib/isc/jemalloc_shim.h index f01e256b09..0edb09267d 100644 --- a/lib/isc/jemalloc_shim.h +++ b/lib/isc/jemalloc_shim.h @@ -66,7 +66,7 @@ mallocx(size_t size, int flags) { INSIST(ptr != NULL); if ((flags & MALLOCX_ZERO) != 0) { - memset(ptr, 0, size); + memset(ptr, 0, sallocx(ptr, flags)); } return (ptr); @@ -83,7 +83,7 @@ sdallocx(void *ptr, size_t size, int flags) { static inline void * rallocx(void *ptr, size_t size, int flags) { void *new_ptr; - size_t old_size; + size_t old_size, new_size; REQUIRE(size != 0); @@ -94,8 +94,12 @@ rallocx(void *ptr, size_t size, int flags) { new_ptr = realloc(ptr, size); INSIST(new_ptr != NULL); - if ((flags & MALLOCX_ZERO) != 0 && size > old_size) { - memset((uint8_t *)new_ptr + old_size, 0, size - old_size); + if ((flags & MALLOCX_ZERO) != 0) { + new_size = sallocx(new_ptr, flags); + if (new_size > old_size) { + memset((uint8_t *)new_ptr + old_size, 0, + new_size - old_size); + } } return (new_ptr);