|
|
b62b43 |
From fb97a1cddbda4019e327fa736972a1c7433fedaa Mon Sep 17 00:00:00 2001
|
|
|
b62b43 |
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
|
|
b62b43 |
Date: Fri, 11 Sep 2020 09:53:03 +0300
|
|
|
b62b43 |
Subject: [PATCH] lib-mail: message-parser - Fix assert-crash when enforcing
|
|
|
b62b43 |
MIME part limit
|
|
|
b62b43 |
|
|
|
b62b43 |
The limit could have been exceeded with message/rfc822 parts.
|
|
|
b62b43 |
---
|
|
|
b62b43 |
src/lib-mail/message-parser.c | 3 +-
|
|
|
b62b43 |
src/lib-mail/test-message-parser.c | 82 ++++++++++++++++++++++++++++++
|
|
|
b62b43 |
2 files changed, 84 insertions(+), 1 deletion(-)
|
|
|
b62b43 |
|
|
|
b62b43 |
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
|
|
|
b62b43 |
index 6ab4c3266f..40a504da0a 100644
|
|
|
b62b43 |
--- a/src/lib-mail/message-parser.c
|
|
|
b62b43 |
+++ b/src/lib-mail/message-parser.c
|
|
|
b62b43 |
@@ -703,7 +703,8 @@ static int parse_next_header(struct message_parser_ctx *ctx,
|
|
|
b62b43 |
ctx->multipart = FALSE;
|
|
|
b62b43 |
ctx->parse_next_block = parse_next_body_to_boundary;
|
|
|
b62b43 |
} else if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0 &&
|
|
|
b62b43 |
- !parse_too_many_nested_mime_parts(ctx)) {
|
|
|
b62b43 |
+ !parse_too_many_nested_mime_parts(ctx) &&
|
|
|
b62b43 |
+ ctx->total_parts_count < ctx->max_total_mime_parts) {
|
|
|
b62b43 |
ctx->parse_next_block = parse_next_body_message_rfc822_init;
|
|
|
b62b43 |
} else {
|
|
|
b62b43 |
part->flags &= ~MESSAGE_PART_FLAG_MESSAGE_RFC822;
|
|
|
b62b43 |
diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c
|
|
|
b62b43 |
index 8c5a3404f1..c4e117afc7 100644
|
|
|
b62b43 |
--- a/src/lib-mail/test-message-parser.c
|
|
|
b62b43 |
+++ b/src/lib-mail/test-message-parser.c
|
|
|
b62b43 |
@@ -1127,6 +1127,87 @@ static const char input_msg[] =
|
|
|
b62b43 |
test_end();
|
|
|
b62b43 |
}
|
|
|
b62b43 |
|
|
|
b62b43 |
+static void test_message_parser_mime_part_limit_rfc822(void)
|
|
|
b62b43 |
+{
|
|
|
b62b43 |
+static const char input_msg[] =
|
|
|
b62b43 |
+"Content-Type: multipart/mixed; boundary=\"1\"\n"
|
|
|
b62b43 |
+"\n"
|
|
|
b62b43 |
+"--1\n"
|
|
|
b62b43 |
+"Content-Type: multipart/mixed; boundary=\"2\"\n"
|
|
|
b62b43 |
+"\n"
|
|
|
b62b43 |
+"--2\n"
|
|
|
b62b43 |
+"Content-Type: message/rfc822\n"
|
|
|
b62b43 |
+"\n"
|
|
|
b62b43 |
+"Content-Type: text/plain\n"
|
|
|
b62b43 |
+"\n"
|
|
|
b62b43 |
+"1\n"
|
|
|
b62b43 |
+"--2\n"
|
|
|
b62b43 |
+"Content-Type: message/rfc822\n"
|
|
|
b62b43 |
+"\n"
|
|
|
b62b43 |
+"Content-Type: text/plain\n"
|
|
|
b62b43 |
+"\n"
|
|
|
b62b43 |
+"22\n"
|
|
|
b62b43 |
+"--1\n"
|
|
|
b62b43 |
+"Content-Type: message/rfc822\n"
|
|
|
b62b43 |
+"\n"
|
|
|
b62b43 |
+"Content-Type: text/plain\n"
|
|
|
b62b43 |
+"\n"
|
|
|
b62b43 |
+"333\n";
|
|
|
b62b43 |
+ const struct message_parser_settings parser_set = {
|
|
|
b62b43 |
+ .max_total_mime_parts = 3,
|
|
|
b62b43 |
+ };
|
|
|
b62b43 |
+ struct message_parser_ctx *parser;
|
|
|
b62b43 |
+ struct istream *input;
|
|
|
b62b43 |
+ struct message_part *parts, *part;
|
|
|
b62b43 |
+ struct message_block block;
|
|
|
b62b43 |
+ pool_t pool;
|
|
|
b62b43 |
+ int ret;
|
|
|
b62b43 |
+
|
|
|
b62b43 |
+ test_begin("message parser mime part limit rfc822");
|
|
|
b62b43 |
+ pool = pool_alloconly_create("message parser", 10240);
|
|
|
b62b43 |
+ input = test_istream_create(input_msg);
|
|
|
b62b43 |
+
|
|
|
b62b43 |
+ parser = message_parser_init(pool, input, &parser_set);
|
|
|
b62b43 |
+ while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
|
|
|
b62b43 |
+ test_assert(ret < 0);
|
|
|
b62b43 |
+ message_parser_deinit(&parser, &parts;;
|
|
|
b62b43 |
+
|
|
|
b62b43 |
+ part = parts;
|
|
|
b62b43 |
+ test_assert(part->children_count == 2);
|
|
|
b62b43 |
+ test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
|
|
|
b62b43 |
+ test_assert(part->header_size.lines == 2);
|
|
|
b62b43 |
+ test_assert(part->header_size.physical_size == 45);
|
|
|
b62b43 |
+ test_assert(part->header_size.virtual_size == 45+2);
|
|
|
b62b43 |
+ test_assert(part->body_size.lines == 21);
|
|
|
b62b43 |
+ test_assert(part->body_size.physical_size == 238);
|
|
|
b62b43 |
+ test_assert(part->body_size.virtual_size == 238+21);
|
|
|
b62b43 |
+
|
|
|
b62b43 |
+ part = parts->children;
|
|
|
b62b43 |
+ test_assert(part->children_count == 1);
|
|
|
b62b43 |
+ test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
|
|
|
b62b43 |
+ test_assert(part->header_size.lines == 2);
|
|
|
b62b43 |
+ test_assert(part->header_size.physical_size == 45);
|
|
|
b62b43 |
+ test_assert(part->header_size.virtual_size == 45+2);
|
|
|
b62b43 |
+ test_assert(part->body_size.lines == 18);
|
|
|
b62b43 |
+ test_assert(part->body_size.physical_size == 189);
|
|
|
b62b43 |
+ test_assert(part->body_size.virtual_size == 189+18);
|
|
|
b62b43 |
+
|
|
|
b62b43 |
+ part = parts->children->children;
|
|
|
b62b43 |
+ test_assert(part->children_count == 0);
|
|
|
b62b43 |
+ test_assert(part->flags == MESSAGE_PART_FLAG_IS_MIME);
|
|
|
b62b43 |
+ test_assert(part->header_size.lines == 2);
|
|
|
b62b43 |
+ test_assert(part->header_size.physical_size == 30);
|
|
|
b62b43 |
+ test_assert(part->header_size.virtual_size == 30+2);
|
|
|
b62b43 |
+ test_assert(part->body_size.lines == 15);
|
|
|
b62b43 |
+ test_assert(part->body_size.physical_size == 155);
|
|
|
b62b43 |
+ test_assert(part->body_size.virtual_size == 155+15);
|
|
|
b62b43 |
+
|
|
|
b62b43 |
+ test_parsed_parts(input, parts);
|
|
|
b62b43 |
+ i_stream_unref(&input);
|
|
|
b62b43 |
+ pool_unref(&pool);
|
|
|
b62b43 |
+ test_end();
|
|
|
b62b43 |
+}
|
|
|
b62b43 |
+
|
|
|
b62b43 |
int main(void)
|
|
|
b62b43 |
{
|
|
|
b62b43 |
static void (*const test_functions[])(void) = {
|
|
|
b62b43 |
@@ -1301,6 +1382,7 @@ int main(void)
|
|
|
b62b43 |
test_message_parser_mime_part_nested_limit,
|
|
|
b62b43 |
test_message_parser_mime_part_nested_limit_rfc822,
|
|
|
b62b43 |
test_message_parser_mime_part_limit,
|
|
|
b62b43 |
+ test_message_parser_mime_part_limit_rfc822,
|
|
|
b62b43 |
NULL
|
|
|
b62b43 |
};
|
|
|
b62b43 |
return test_run(test_functions);
|