From: Timo Sirainen Date: Fri, 24 Mar 2017 12:46:05 +0000 (+0200) Subject: lib-mail: Fix read overflow / crash in message_header_decode() X-Git-Tag: 2.2.29.rc1~86 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dfabd74c045675a1bfc583f7fe0fab7868c789f9;p=thirdparty%2Fdovecot%2Fcore.git lib-mail: Fix read overflow / crash in message_header_decode() If the input string was "=?charset?Q|B?text?", the code attempted to look up the character after it. And if it was "=", the callback was called with size=-1, which ends up in a crash. --- diff --git a/src/lib-mail/message-header-decode.c b/src/lib-mail/message-header-decode.c index 46372b8587..fb25decbd5 100644 --- a/src/lib-mail/message-header-decode.c +++ b/src/lib-mail/message-header-decode.c @@ -24,7 +24,7 @@ message_header_decode_encoded(const unsigned char *data, size_t size, break; } } - if (i == size || data[i+1] != '=') { + if (i+1 >= size || data[i+1] != '=') { /* invalid block */ return 0; } @@ -128,6 +128,7 @@ void message_header_decode(const unsigned char *data, size_t size, } if (size != start_pos) { + i_assert(size > start_pos); (void)callback(data + start_pos, size - start_pos, NULL, context); } diff --git a/src/lib-mail/test-message-header-decode.c b/src/lib-mail/test-message-header-decode.c index 901fb61f7a..31b9aec596 100644 --- a/src/lib-mail/test-message-header-decode.c +++ b/src/lib-mail/test-message-header-decode.c @@ -50,6 +50,16 @@ static void test_message_header_decode(void) test_end(); } +static void test_message_header_decode_read_overflow(void) +{ + const unsigned char input[] = "=?utf-8?Q?=EF?="; + string_t *dest = t_str_new(32); + + test_begin("message header decode read overflow"); + message_header_decode_utf8(input, sizeof(input)-2, dest, NULL); + test_end(); +} + static void test_message_header_decode_encode_random(void) { string_t *encoded, *decoded; @@ -94,6 +104,7 @@ int main(void) { static void (*test_functions[])(void) = { test_message_header_decode, + test_message_header_decode_read_overflow, test_message_header_decode_encode_random, NULL };