]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix ISC_MEM_ZERO on allocators with malloc_usable_size()
authorTony Finch <dot@dotat.at>
Fri, 3 Feb 2023 12:29:00 +0000 (12:29 +0000)
committerTony Finch <dot@dotat.at>
Mon, 6 Feb 2023 11:21:12 +0000 (11:21 +0000)
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
lib/isc/jemalloc_shim.h

diff --git a/CHANGES b/CHANGES
index 18820e0b4748c10303f99e0f4e8efc8051ca819d..748fe8afb57120fccc2ca12166a9d21202c15a80 100644 (file)
--- 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]
 
index f01e256b092e0793445d6c37178e2540da6c133c..0edb09267d9881c2ac4fc25d7efa72a8d08924b1 100644 (file)
@@ -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);