From c38df6196d38e37a8bb6c517fb03afe59e30f6d2 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Mon, 9 Mar 2020 11:11:04 +0200 Subject: [PATCH] lib: DEBUG: Fix potential crash in handling "Growing data stack" debug message This could have only happened when data_stack_grow event was enabled and when --enable-devel-checks was used. --- src/lib/data-stack.c | 4 ++-- src/lib/test-data-stack.c | 43 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/lib/data-stack.c b/src/lib/data-stack.c index 801c4e99d7..fe7361402c 100644 --- a/src/lib/data-stack.c +++ b/src/lib/data-stack.c @@ -490,11 +490,11 @@ static void *t_malloc_real(size_t size, bool permanent) if (permanent) current_block->left -= alloc_size; - if (warn) { + if (warn) T_BEGIN { /* warn after allocation, so if e_debug() wants to allocate more memory we don't go to infinite loop */ data_stack_send_grow_event(alloc_size); - } + } T_END; #ifdef DEBUG memcpy(ret, &size, sizeof(size)); ret = PTR_OFFSET(ret, MEM_ALIGN(sizeof(size))); diff --git a/src/lib/test-data-stack.c b/src/lib/test-data-stack.c index d37cf5ac7f..70f8238897 100644 --- a/src/lib/test-data-stack.c +++ b/src/lib/test-data-stack.c @@ -37,7 +37,7 @@ test_ds_grow_event_callback(struct event *event, field = event_find_field_nonrecursive(event, "frame_marker"); test_assert(field != NULL && field->value_type == EVENT_FIELD_VALUE_TYPE_STR && - strstr(field->value.str, "test-data-stack.c") != NULL); + strstr(field->value.str, "data-stack.c") != NULL); return TRUE; } @@ -96,6 +96,46 @@ static void test_ds_get_bytes_available(void) test_end(); } +static void ATTR_FORMAT(2, 0) +test_ds_growing_debug(const struct failure_context *ctx ATTR_UNUSED, + const char *format, va_list args) +{ + ds_grow_event_count++; + (void)t_strdup_vprintf(format, args); +} + +static void test_ds_grow_in_event(void) +{ + size_t i, alloc1 = 8096; + unsigned char *buf; + const char *error; + + test_begin("data-stack grow in event"); + + struct event_filter *filter = event_filter_create(); + event_set_global_debug_log_filter(filter); + test_assert(event_filter_parse("event=data_stack_grow", filter, &error) == 0); + event_filter_unref(&filter); + + i_set_debug_handler(test_ds_growing_debug); + buf = t_buffer_get(alloc1); + for (i = 0; i < alloc1; i++) + buf[i] = i; + + test_assert(ds_grow_event_count == 0); + buf = t_buffer_reget(buf, 65536); + test_assert(ds_grow_event_count == 1); + for (i = 0; i < alloc1; i++) { + if (buf[i] != (unsigned char)i) + break; + } + test_assert(i == alloc1); + + i_set_debug_handler(default_error_handler); + event_unset_global_debug_log_filter(); + test_end(); +} + static void test_ds_buffers(void) { test_begin("data-stack buffer growth"); @@ -286,6 +326,7 @@ void test_data_stack(void) void (*tests[])(void) = { test_ds_grow_event, test_ds_get_bytes_available, + test_ds_grow_in_event, test_ds_buffers, test_ds_realloc, test_ds_recursive, -- 2.47.3