I have a message with over a 1000 embedded attachments(!), and it breaks Dovecot. The issue appears to be buffer management. There is some logic in the function message_part_deserialize_part that seems to assume that the message part structure is in a contiguous array, but that doesn't seem to be the case. I haven't been able to figure out enough about the memory management in Dovecot to fix the problem. Below is a horrible workaround that just allocates a lot more memory for the message part array, so that it remains contiguous. *** mail-index-update.c.orig Wed Mar 26 10:41:55 2003 --- mail-index-update.c Sun Apr 20 16:53:45 2003 *************** *** 498,504 **** if (cache_fields & DATA_FIELD_MESSAGEPART) { t_push(); ! buf = buffer_create_dynamic(data_stack_pool, 2048, (size_t)-1); message_part_serialize(part, buf); --- 498,504 ---- if (cache_fields & DATA_FIELD_MESSAGEPART) { t_push(); ! buf = buffer_create_dynamic(data_stack_pool, 51200, (size_t)-1); message_part_serialize(part, buf);
Timo Sirainen
2003-Apr-21 16:47 UTC
[dovecot] Re: Message with lots of attachments breaks Dovecot
On Mon, 2003-04-21 at 04:37, Tim Hunt wrote:> I have a message with over a 1000 embedded attachments(!), and it breaks > Dovecot. The issue appears to be buffer management.I think it crashes because of bug in data-stack.c. This should fix it: Index: data-stack.c ==================================================================RCS file: /home/cvs/dovecot/src/lib/data-stack.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- data-stack.c 27 Jan 2003 00:46:29 -0000 1.17 +++ data-stack.c 26 Mar 2003 14:58:33 -0000 1.18 @@ -121,9 +121,13 @@ static void free_blocks(struct stack_block *block) { + struct stack_block *next; + /* free all the blocks, except if any of them is bigger than unused_block, replace it */ while (block != NULL) { + next = block->next; + if (unused_block == NULL || block->size > unused_block->size) { free(unused_block); unused_block = block; @@ -131,7 +135,7 @@ free(block); } - block = block->next; + block = next; } }