]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add isc_mem_callocate() for safer array allocation
authorTony Finch <fanf@isc.org>
Tue, 6 Jun 2023 14:15:31 +0000 (15:15 +0100)
committerOndřej Surý <ondrej@isc.org>
Tue, 27 Jun 2023 10:38:09 +0000 (12:38 +0200)
As well as clearing the fresh memory, `calloc()`-like functions must
ensure that the count and size do not overflow when multiplied.

Use `isc_mem_callocate()` in `isc__uv_calloc()`.

lib/isc/include/isc/mem.h
lib/isc/mem.c
lib/isc/uv.c

index 0a0c87759468900dff248831cce00ae9b9786bf7..74083b7b614294d13b5793efbbefbe101b5596b0 100644 (file)
@@ -167,6 +167,8 @@ extern unsigned int isc_mem_defaultflags;
        ISCMEMFUNC(allocate)((c), (s), 0 _ISC_MEM_FILELINE)
 #define isc_mem_allocatex(c, s, f) \
        ISCMEMFUNC(allocate)((c), (s), (f)_ISC_MEM_FILELINE)
+#define isc_mem_callocate(c, n, s) \
+       ISCMEMFUNC(callocate)((c), (n), (s), 0 _ISC_MEM_FILELINE)
 #define isc_mem_reallocate(c, p, s) \
        ISCMEMFUNC(reallocate)((c), (p), (s), 0 _ISC_MEM_FILELINE)
 #define isc_mem_reallocatex(c, p, s, f) \
@@ -513,6 +515,9 @@ void *ISCMEMFUNC(reget)(isc_mem_t *, void *, size_t, size_t,
 ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
 void *ISCMEMFUNC(allocate)(isc_mem_t *, size_t, int _ISC_MEM_FLARG);
 
+ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
+void *ISCMEMFUNC(callocate)(isc_mem_t *, size_t, size_t, int _ISC_MEM_FLARG);
+
 ISC_ATTR_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
 void *ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t, int _ISC_MEM_FLARG);
 
index 31052364781ad1f43f1d027b11997d058257de9e..593b610890412de9c7b50ac0b04a4d5d6889cd39 100644 (file)
@@ -28,6 +28,7 @@
 #include <isc/mutex.h>
 #include <isc/once.h>
 #include <isc/os.h>
+#include <isc/overflow.h>
 #include <isc/refcount.h>
 #include <isc/strerr.h>
 #include <isc/string.h>
@@ -802,6 +803,13 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size, int flags FLARG) {
        return (ptr);
 }
 
+void *
+isc__mem_callocate(isc_mem_t *ctx, size_t count, size_t size, int flags FLARG) {
+       size_t bytes = ISC_CHECKED_MUL(count, size);
+       return (isc__mem_allocate(ctx, bytes,
+                                 (flags | ISC_MEM_ZERO) FLARG_PASS));
+}
+
 void *
 isc__mem_reget(isc_mem_t *ctx, void *old_ptr, size_t old_size, size_t new_size,
               int flags FLARG) {
index 8b1ef7398e02e2fab8fb55bd060632ac08f62edd..41b926d27020f5b60a236fdfd3c78e6baa5ba33c 100644 (file)
@@ -116,19 +116,7 @@ isc__uv_realloc(void *ptr, size_t size) {
 
 static void *
 isc__uv_calloc(size_t count, size_t size) {
-       void *ptr;
-       size_t res;
-#if HAVE_BUILTIN_MUL_OVERFLOW
-       bool overflow = __builtin_mul_overflow(count, size, &res);
-       RUNTIME_CHECK(!overflow);
-#else
-       res = count * size;
-       REQUIRE(count == 0 || res / count == size);
-#endif
-
-       ptr = isc_mem_allocatex(isc__uv_mctx, res, ISC_MEM_ZERO);
-
-       return (ptr);
+       return (isc_mem_callocate(isc__uv_mctx, count, size));
 }
 
 static void