changeset 21822:c09853ffcc46

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.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 24 Mar 2017 14:46:05 +0200
parents 4e3fcaa8ab3f
children c7975678d4dc
files src/lib-mail/message-header-decode.c src/lib-mail/test-message-header-decode.c
diffstat 2 files changed, 13 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-mail/message-header-decode.c	Fri Dec 16 22:18:02 2016 +0200
+++ b/src/lib-mail/message-header-decode.c	Fri Mar 24 14:46:05 2017 +0200
@@ -24,7 +24,7 @@
 				break;
 		}
 	}
-	if (i == size || data[i+1] != '=') {
+	if (i+1 >= size || data[i+1] != '=') {
 		/* invalid block */
 		return 0;
 	}
@@ -128,6 +128,7 @@
 	}
 
 	if (size != start_pos) {
+		i_assert(size > start_pos);
 		(void)callback(data + start_pos, size - start_pos,
 			       NULL, context);
 	}
--- a/src/lib-mail/test-message-header-decode.c	Fri Dec 16 22:18:02 2016 +0200
+++ b/src/lib-mail/test-message-header-decode.c	Fri Mar 24 14:46:05 2017 +0200
@@ -50,6 +50,16 @@
 	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 @@
 {
 	static void (*test_functions[])(void) = {
 		test_message_header_decode,
+		test_message_header_decode_read_overflow,
 		test_message_header_decode_encode_random,
 		NULL
 	};