[Dovecot] Message parser loops on certain messages (e.g. with a trailing CR character)
Hi,
dovecot's message parser enters an endless loop when fed with certain multipart messages with stray CR characters.
parse_next_body_to_boundary() assumes the '\r' might be the beginning of a boundary line, reducing the block size by one:
src/lib-mail/message-parser.c: 404 /* no linefeeds in this block. we can just skip it. */ 405 ret = 0; 406 if (block_r->data[block_r->size-1] == '\r') { 407 /* this may be the beginning of the \r\n--boundary */ 408 block_r->size--; 409 }
For a block size of 1 (e.g. the trailing '\r' character), dovecot ends up processing zero-sized blocks, calling message_parser_read_more() without skipping the input stream:
... #6 0x00007f94f49374c7 in i_stream_read (stream=0xbe2fc8) at istream.c:167 #7 0x00007f94f49383d5 in i_stream_read_data (stream=0xbe2fc8, data_r=0x7fff2141d6b0, size_r=0x7fff2141d6b8, threshold=1) at istream.c:497 #8 0x00007f94f4918c2b in message_parser_read_more (ctx=0xbe7c10, block_r=0x7fff2141d6a0, full_r=0x7fff2141d667) at message-parser.c:128 #9 0x00007f94f491af67 in message_parser_parse_next_block (ctx=0xbe7c10, block_r=0x7fff2141d6a0) at message-parser.c:1012 #10 0x00007f94f491b2fb in message_parser_parse_body (ctx=0xbe7c10, hdr_callback=0x7f94f4c69a75 <parse_bodystructure_part_header>, context=0xbf0450) at message-parser.c:1075 #11 0x00007f94f4c6a876 in index_mail_parse_body (mail=0xbecd00, field=MAIL_CACHE_IMAP_BODYSTRUCTURE) at index-mail.c:895 #12 0x00007f94f4c6aedb in index_mail_parse_bodystructure (mail=0xbecd00, field=MAIL_CACHE_IMAP_BODYSTRUCTURE) at index-mail.c:1046 #13 0x00007f94f4c6b4a5 in index_mail_get_special (_mail=0xbecd00, field=MAIL_FETCH_IMAP_BODYSTRUCTURE, value_r=0x7fff2141d958) at index-mail.c:1170 #14 0x00007f94f4bfab53 in maildir_mail_get_special (_mail=0xbecd00, field=MAIL_FETCH_IMAP_BODYSTRUCTURE, value_r=0x7fff2141d958) at maildir-mail.c:570 #15 0x00007f94f4c36ea1 in mail_get_special (mail=0xbecd00, field=MAIL_FETCH_IMAP_BODYSTRUCTURE, value_r=0x7fff2141d958) at mail.c:269 #16 0x000000000041c5d7 in fetch_bodystructure (ctx=0xbd6a48, mail=0xbecd00, context=0x0) at imap-fetch.c:678 ...
You will find a sample message attached to this mail.
I have added a check to see if the parser is past the EOF (and omit reducing the block size then) as a band-aid fix, but this might call for a more elegant solution.
Best regards, Tomasz Potêga
[Wirtualna Polska] <http://www.wp.pl>
Znajdziesz nas tutaj:
[Wp na Facebooku] <https://www.facebook.com/WirtualnaPolska> [Wp na Twitterze] <https://twitter.com/wirtualnapolska> [Wp na SlideShare] <http://www.slideshare.net/wirtualnapolska> [Wp w Google+] <https://plus.google.com/+wppl> [Wp na YouTube] <https://www.youtube.com/user/wptvwppl>
"WIRTUALNA POLSKA" Spółka Akcyjna z siedzibą w Gdańsku przy ul. Traugutta 115 C, wpisana do Krajowego Rejestru Sądowego - Rejestru Przedsiębiorców prowadzonego przez Sąd Rejonowy Gdańsk - Północ w Gdańsku pod numerem KRS 0000068548, o kapitale zakładowym 67.980.024,00 złotych opłaconym w całości oraz Numerze Identyfikacji Podatkowej 957-07-51-216.
On 5.11.2013, at 16.02, Tomasz Potega <tpotega@wp-sa.pl> wrote:
dovecot's message parser enters an endless loop when fed with certain multipart messages with stray CR characters.
parse_next_body_to_boundary() assumes the '\r' might be the beginning of a boundary line, reducing the block size by one:
Thanks, fixed: http://hg.dovecot.org/dovecot-2.2/rev/aa1aede0f7f2
I have added a check to see if the parser is past the EOF (and omit reducing the block size then) as a band-aid fix, but this might call for a more elegant solution.
I think I did the same fix.
Also I don’t think it’s possible to normally use this as a DoS attack against users, because with mail_save_crlf=no (default) the CRs are stripped. And with mail_save_crlf=yes I’m not sure if such message can even pass through SMTP servers.
participants (2)
-
Timo Sirainen
-
Tomasz Potega