# HG changeset patch # User Timo Sirainen # Date 1496823843 -10800 # Node ID 54260e47d2e1e73bc5f45924ca72f5dda27e14fc # Parent d02fc7312081f7eedb56285d18703a6c679e0b4d lib: Add i_realloc_type() for i_realloc() that checks for overflows diff -r d02fc7312081 -r 54260e47d2e1 src/lib/Makefile.am --- a/src/lib/Makefile.am Thu May 12 05:40:29 2016 -0400 +++ b/src/lib/Makefile.am Wed Jun 07 11:24:03 2017 +0300 @@ -325,6 +325,7 @@ test-hash-format.c \ test-hash-method.c \ test-hex-binary.c \ + test-imem.c \ test-ioloop.c \ test-iso8601-date.c \ test-iostream-temp.c \ diff -r d02fc7312081 -r 54260e47d2e1 src/lib/imem.h --- a/src/lib/imem.h Thu May 12 05:40:29 2016 -0400 +++ b/src/lib/imem.h Wed Jun 07 11:24:03 2017 +0300 @@ -6,6 +6,8 @@ extern pool_t default_pool; #define i_new(type, count) p_new(default_pool, type, count) +#define i_realloc_type(mem, type, old_count, new_count) \ + p_realloc_type(default_pool, mem, type, old_count, new_count) void *i_malloc(size_t size) ATTR_MALLOC ATTR_RETURNS_NONNULL; void *i_realloc(void *mem, size_t old_size, size_t new_size) diff -r d02fc7312081 -r 54260e47d2e1 src/lib/mempool.h --- a/src/lib/mempool.h Thu May 12 05:40:29 2016 -0400 +++ b/src/lib/mempool.h Wed Jun 07 11:24:03 2017 +0300 @@ -73,9 +73,18 @@ old_size + 1. */ size_t pool_get_exp_grown_size(pool_t pool, size_t old_size, size_t min_size); +/* We require sizeof(type) to be <= UINT_MAX. This allows compiler to optimize + away the entire MALLOC_MULTIPLY() call on 64bit systems. */ #define p_new(pool, type, count) \ ((type *) p_malloc(pool, MALLOC_MULTIPLY((unsigned int)sizeof(type), (count))) + \ COMPILE_ERROR_IF_TRUE(sizeof(type) > UINT_MAX)) + +#define p_realloc_type(pool, mem, type, old_count, new_count) \ + ((type *) p_realloc(pool, mem, \ + MALLOC_MULTIPLY((unsigned int)sizeof(type), (old_count)), \ + MALLOC_MULTIPLY((unsigned int)sizeof(type), (new_count))) + \ + COMPILE_ERROR_IF_TRUE(sizeof(type) > UINT_MAX)) + static inline void * ATTR_MALLOC ATTR_RETURNS_NONNULL p_malloc(pool_t pool, size_t size) { diff -r d02fc7312081 -r 54260e47d2e1 src/lib/test-imem.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/test-imem.c Wed Jun 07 11:24:03 2017 +0300 @@ -0,0 +1,61 @@ +/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" + +struct test_struct { + uint32_t num[10]; +}; + +static void test_imem_alloc(void) +{ + struct test_struct ab, bc, cd, de; + + test_begin("imem allocs"); + + memset(ab.num, 0xab, sizeof(ab.num)); + memset(bc.num, 0xbc, sizeof(bc.num)); + memset(cd.num, 0xcd, sizeof(cd.num)); + memset(de.num, 0xde, sizeof(de.num)); + + /* regular alloc */ + struct test_struct *s1 = i_new(struct test_struct, 2); + struct test_struct *s2 = i_malloc(sizeof(struct test_struct) * 2); + s1[0] = ab; s2[0] = ab; + s1[1] = bc; s2[1] = bc; + test_assert(memcmp(s1, s2, sizeof(struct test_struct) * 2) == 0); + + /* realloc */ + s1 = i_realloc_type(s1, struct test_struct, 2, 4); + s2 = i_realloc(s2, sizeof(struct test_struct) * 2, + sizeof(struct test_struct) * 4); + s1[2] = cd; s2[2] = cd; + s1[3] = de; s2[3] = de; + test_assert(memcmp(&s1[0], &ab, sizeof(ab)) == 0); + test_assert(memcmp(&s1[1], &bc, sizeof(bc)) == 0); + test_assert(memcmp(&s1[2], &cd, sizeof(cd)) == 0); + test_assert(memcmp(&s1[3], &de, sizeof(de)) == 0); + test_assert(memcmp(s1, s2, sizeof(struct test_struct) * 4) == 0); + + /* freeing realloced memory */ + i_free(s1); + i_free(s2); + test_assert(s1 == NULL); + test_assert(s2 == NULL); + + /* allcating new memory with realloc */ + s1 = i_realloc_type(NULL, struct test_struct, 0, 2); + s2 = i_realloc(NULL, 0, sizeof(struct test_struct) * 2); + s1[0] = ab; s2[0] = ab; + s1[1] = bc; s2[1] = bc; + test_assert(memcmp(s1, s2, sizeof(struct test_struct) * 2) == 0); + + i_free(s1); + i_free(s2); + + test_end(); +} + +void test_imem(void) +{ + test_imem_alloc(); +} diff -r d02fc7312081 -r 54260e47d2e1 src/lib/test-lib.c --- a/src/lib/test-lib.c Thu May 12 05:40:29 2016 -0400 +++ b/src/lib/test-lib.c Wed Jun 07 11:24:03 2017 +0300 @@ -20,6 +20,7 @@ test_hash_format, test_hash_method, test_hex_binary, + test_imem, test_ioloop, test_iso8601_date, test_iostream_temp, diff -r d02fc7312081 -r 54260e47d2e1 src/lib/test-lib.h --- a/src/lib/test-lib.h Thu May 12 05:40:29 2016 -0400 +++ b/src/lib/test-lib.h Wed Jun 07 11:24:03 2017 +0300 @@ -21,6 +21,7 @@ void test_hash_format(void); void test_hash_method(void); void test_hex_binary(void); +void test_imem(void); void test_ioloop(void); void test_iso8601_date(void); void test_iostream_temp(void);