From: Tony Finch Date: Tue, 6 Jun 2023 14:15:31 +0000 (+0100) Subject: Add isc_mem_callocate() for safer array allocation X-Git-Tag: v9.19.15~15^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=81d73600c1c7969fae5f7ea34ba8446199df4f74;p=thirdparty%2Fbind9.git Add isc_mem_callocate() for safer array allocation 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()`. --- diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index 0a0c8775946..74083b7b614 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -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); diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 31052364781..593b6108904 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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) { diff --git a/lib/isc/uv.c b/lib/isc/uv.c index 8b1ef7398e0..41b926d2702 100644 --- a/lib/isc/uv.c +++ b/lib/isc/uv.c @@ -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