changeset 7096:bf1d4795085f HEAD

If giving pool_alloconly_create() less than 40 bytes as the initial size with 32bit systems, destroying the pool crashed.
author Timo Sirainen <tss@iki.fi>
date Thu, 03 Jan 2008 21:18:39 +0200
parents e06ee42ad5f9
children 618472c2c3c5
files src/lib/mempool-alloconly.c src/tests/test-lib.c
diffstat 2 files changed, 50 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/mempool-alloconly.c	Wed Jan 02 02:08:31 2008 +0200
+++ b/src/lib/mempool-alloconly.c	Thu Jan 03 21:18:39 2008 +0200
@@ -96,10 +96,11 @@
 pool_t pool_alloconly_create(const char *name ATTR_UNUSED, size_t size)
 {
 	struct alloconly_pool apool, *new_apool;
-	size_t min_alloc = sizeof(struct alloconly_pool) + SIZEOF_POOLBLOCK;
+	size_t min_alloc = MEM_ALIGN(sizeof(struct alloconly_pool)) +
+		SIZEOF_POOLBLOCK;
 
 #ifdef DEBUG
-	min_alloc += strlen(name) + 1;
+	min_alloc += MEM_ALIGN(strlen(name) + 1);
 #endif
 
 	/* create a fake alloconly_pool so we can call block_alloc() */
@@ -114,6 +115,8 @@
 	/* now allocate the actual alloconly_pool from the created block */
 	new_apool = p_new(&apool.pool, struct alloconly_pool, 1);
 	*new_apool = apool;
+	/* the pool allocation must be from the first block */
+	i_assert(apool.block->prev == NULL);
 #ifdef DEBUG
 	if (strncmp(name, MEMPOOL_GROWING, strlen(MEMPOOL_GROWING)) == 0) {
 		name += strlen(MEMPOOL_GROWING);
--- a/src/tests/test-lib.c	Wed Jan 02 02:08:31 2008 +0200
+++ b/src/tests/test-lib.c	Thu Jan 03 21:18:39 2008 +0200
@@ -190,6 +190,49 @@
 	test_out_reason("aqueue", reason == NULL, reason);
 }
 
+static bool mem_has_bytes(const void *mem, size_t size, uint8_t b)
+{
+	const uint8_t *bytes = mem;
+	unsigned int i;
+
+	for (i = 0; i < size; i++) {
+		if (bytes[i] != b)
+			return FALSE;
+	}
+	return TRUE;
+}
+
+static void test_mempool_alloconly(void)
+{
+#define PMALLOC_MAX_COUNT 128
+	pool_t pool;
+	unsigned int i, j, k;
+	void *mem[PMALLOC_MAX_COUNT + 1];
+	bool success = TRUE;
+
+	for (i = 0; i < 64; i++) {
+		for (j = 1; j <= 128; j++) {
+			pool = pool_alloconly_create("test", i);
+			mem[0] = p_malloc(pool, j);
+			memset(mem[0], j, j);
+
+			for (k = 1; k <= PMALLOC_MAX_COUNT; k++) {
+				mem[k] = p_malloc(pool, k);
+				memset(mem[k], k, k);
+			}
+
+			if (!mem_has_bytes(mem[0], j, j))
+				success = FALSE;
+			for (k = 1; k <= PMALLOC_MAX_COUNT; k++) {
+				if (!mem_has_bytes(mem[k], k, k))
+					success = FALSE;
+			}
+			pool_unref(&pool);
+		}
+	}
+	test_out("mempool_alloconly", success);
+}
+
 static void test_seq_range_array(void)
 {
 	static const unsigned int input_min = 1, input_max = 5;
@@ -271,10 +314,11 @@
 int main(void)
 {
 	static void (*test_functions[])(void) = {
+		test_aqueue,
 		test_base64_encode,
 		test_base64_decode,
 		test_bsearch_insert_pos,
-		test_aqueue,
+		test_mempool_alloconly,
 		test_seq_range_array,
 		test_str_sanitize,