From a2cefa2b675273588b6dd82483b181b9afad88fc Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 1 Apr 2022 18:33:08 +0100 Subject: [PATCH] [Minor] Add array allocation methods to handle integer overflow --- src/libutil/mem_pool.c | 19 +++++++++++++++++++ src/libutil/mem_pool.h | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/libutil/mem_pool.c b/src/libutil/mem_pool.c index ac0a28e02..d58be5e08 100644 --- a/src/libutil/mem_pool.c +++ b/src/libutil/mem_pool.c @@ -559,6 +559,25 @@ rspamd_mempool_alloc_ (rspamd_mempool_t * pool, gsize size, gsize alignment, con return memory_pool_alloc_common (pool, size, alignment, RSPAMD_MEMPOOL_NORMAL, loc); } +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW (1UL << (sizeof(gsize) * 4)) + +void * +rspamd_mempool_alloc_array_ (rspamd_mempool_t * pool, gsize nmemb, gsize size, gsize alignment, const gchar *loc) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && G_MAXSIZE / nmemb < size) { + + g_error("alloc_array: overflow %"G_GSIZE_FORMAT" * %"G_GSIZE_FORMAT"", + nmemb, size); + g_abort(); + } + return memory_pool_alloc_common (pool, size, alignment, RSPAMD_MEMPOOL_NORMAL, loc); +} + void * rspamd_mempool_alloc0_ (rspamd_mempool_t * pool, gsize size, gsize alignment, const gchar *loc) { diff --git a/src/libutil/mem_pool.h b/src/libutil/mem_pool.h index 207f5031b..0ca1d3905 100644 --- a/src/libutil/mem_pool.h +++ b/src/libutil/mem_pool.h @@ -154,8 +154,23 @@ rspamd_mempool_t *rspamd_mempool_new_ (gsize size, const gchar *tag, gint flags, */ void *rspamd_mempool_alloc_ (rspamd_mempool_t *pool, gsize size, gsize alignment, const gchar *loc) RSPAMD_ATTR_ALLOC_SIZE(2) RSPAMD_ATTR_ALLOC_ALIGN(MIN_MEM_ALIGNMENT) RSPAMD_ATTR_RETURNS_NONNUL; +/** + * Allocates array handling potential integer overflow + * @param pool + * @param nmemb + * @param size + * @param alignment + * @param loc + * @return + */ +void *rspamd_mempool_alloc_array_ (rspamd_mempool_t *pool, gsize nmemb, gsize size, gsize alignment, const gchar *loc) +RSPAMD_ATTR_ALLOC_SIZE(2) RSPAMD_ATTR_ALLOC_ALIGN(MIN_MEM_ALIGNMENT) RSPAMD_ATTR_RETURNS_NONNUL; #define rspamd_mempool_alloc(pool, size) \ rspamd_mempool_alloc_((pool), (size), MIN_MEM_ALIGNMENT, (G_STRLOC)) +#define rspamd_mempool_alloc_array(pool, nmemb, size) \ + rspamd_mempool_alloc_array_((pool), (nmemb), (size), MIN_MEM_ALIGNMENT, (G_STRLOC)) +#define rspamd_mempool_alloc_array_type(pool, nmemb, type) \ + (type *)rspamd_mempool_alloc_array_((pool), (nmemb), sizeof(type), MIN_MEM_ALIGNMENT, (G_STRLOC)) #define rspamd_mempool_alloc_type(pool, type) \ (type *)(rspamd_mempool_alloc_((pool), sizeof(type), \ MAX(MIN_MEM_ALIGNMENT, RSPAMD_ALIGNOF(type)), (G_STRLOC))) -- 2.39.5