dovecot: Fix CVE-2020-12100

Added patches to fix CVE-2020-12100

Link: http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz

Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
Signed-off-by: Sana Kazi <sanakazisk19@gmail.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
This commit is contained in:
sana kazi
2021-12-03 17:57:19 +05:30
committed by Armin Kuster
parent e0e79bbde2
commit 00ad99f4f9
15 changed files with 1264 additions and 0 deletions
@@ -0,0 +1,76 @@
From 667d353b0f217372e8cc43ea4fe13466689c7ed0 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 11:33:31 +0300
Subject: [PATCH 01/13] lib-mail: message-parser - Add a message_part_finish()
helper function
---
src/lib-mail/message-parser.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index b1de1950a..aaa8dd8b7 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -195,6 +195,13 @@ message_part_append(pool_t pool, struct message_part *parent)
return part;
}
+static void message_part_finish(struct message_parser_ctx *ctx)
+{
+ message_size_add(&ctx->part->parent->body_size, &ctx->part->body_size);
+ message_size_add(&ctx->part->parent->body_size, &ctx->part->header_size);
+ ctx->part = ctx->part->parent;
+}
+
static void parse_next_body_multipart_init(struct message_parser_ctx *ctx)
{
struct message_boundary *b;
@@ -312,19 +319,16 @@ static int parse_part_finish(struct message_parser_ctx *ctx,
struct message_boundary *boundary,
struct message_block *block_r, bool first_line)
{
- struct message_part *part;
size_t line_size;
i_assert(ctx->last_boundary == NULL);
/* get back to parent MIME part, summing the child MIME part sizes
into parent's body sizes */
- for (part = ctx->part; part != boundary->part; part = part->parent) {
- message_size_add(&part->parent->body_size, &part->body_size);
- message_size_add(&part->parent->body_size, &part->header_size);
+ while (ctx->part != boundary->part) {
+ message_part_finish(ctx);
+ i_assert(ctx->part != NULL);
}
- i_assert(part != NULL);
- ctx->part = part;
if (boundary->epilogue_found) {
/* this boundary isn't needed anymore */
@@ -1132,13 +1136,8 @@ int message_parser_parse_next_block(struct message_parser_ctx *ctx,
i_assert(ctx->input->eof || ctx->input->closed ||
ctx->input->stream_errno != 0 ||
ctx->broken_reason != NULL);
- while (ctx->part->parent != NULL) {
- message_size_add(&ctx->part->parent->body_size,
- &ctx->part->body_size);
- message_size_add(&ctx->part->parent->body_size,
- &ctx->part->header_size);
- ctx->part = ctx->part->parent;
- }
+ while (ctx->part->parent != NULL)
+ message_part_finish(ctx);
}
if (block_r->size == 0) {
--
2.11.0
@@ -0,0 +1,71 @@
From de0da7bc8df55521db8fa787f88e293618c96386 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 11:34:22 +0300
Subject: [PATCH 02/13] lib-mail: message-parser - Change message_part_append()
to do all work internally
---
src/lib-mail/message-parser.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index aaa8dd8b7..2edf3e7a6 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -167,16 +167,17 @@ static int message_parser_read_more(struct message_parser_ctx *ctx,
return 1;
}
-static struct message_part *
-message_part_append(pool_t pool, struct message_part *parent)
+static void
+message_part_append(struct message_parser_ctx *ctx)
{
+ struct message_part *parent = ctx->part;
struct message_part *p, *part, **list;
i_assert(parent != NULL);
i_assert((parent->flags & (MESSAGE_PART_FLAG_MULTIPART |
MESSAGE_PART_FLAG_MESSAGE_RFC822)) != 0);
- part = p_new(pool, struct message_part, 1);
+ part = p_new(ctx->part_pool, struct message_part, 1);
part->parent = parent;
for (p = parent; p != NULL; p = p->parent)
p->children_count++;
@@ -192,7 +193,7 @@ message_part_append(pool_t pool, struct message_part *parent)
list = &(*list)->next;
*list = part;
- return part;
+ ctx->part = part;
}
static void message_part_finish(struct message_parser_ctx *ctx)
@@ -220,7 +221,7 @@ static void parse_next_body_multipart_init(struct message_parser_ctx *ctx)
static int parse_next_body_message_rfc822_init(struct message_parser_ctx *ctx,
struct message_block *block_r)
{
- ctx->part = message_part_append(ctx->part_pool, ctx->part);
+ message_part_append(ctx);
return parse_next_header_init(ctx, block_r);
}
@@ -270,7 +271,7 @@ boundary_line_find(struct message_parser_ctx *ctx,
static int parse_next_mime_header_init(struct message_parser_ctx *ctx,
struct message_block *block_r)
{
- ctx->part = message_part_append(ctx->part_pool, ctx->part);
+ message_part_append(ctx);
ctx->part->flags |= MESSAGE_PART_FLAG_IS_MIME;
return parse_next_header_init(ctx, block_r);
--
2.11.0
@@ -0,0 +1,49 @@
From a9800b436fcf1f9633c2b136a9c5cb7a486a8a52 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 11:36:48 +0300
Subject: [PATCH 03/13] lib-mail: message-parser - Optimize updating
children_count
---
src/lib-mail/message-parser.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index 2edf3e7a6..05768a058 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -171,7 +171,7 @@ static void
message_part_append(struct message_parser_ctx *ctx)
{
struct message_part *parent = ctx->part;
- struct message_part *p, *part, **list;
+ struct message_part *part, **list;
i_assert(parent != NULL);
i_assert((parent->flags & (MESSAGE_PART_FLAG_MULTIPART |
@@ -179,8 +179,6 @@ message_part_append(struct message_parser_ctx *ctx)
part = p_new(ctx->part_pool, struct message_part, 1);
part->parent = parent;
- for (p = parent; p != NULL; p = p->parent)
- p->children_count++;
/* set child position */
part->physical_pos =
@@ -200,6 +198,7 @@ static void message_part_finish(struct message_parser_ctx *ctx)
{
message_size_add(&ctx->part->parent->body_size, &ctx->part->body_size);
message_size_add(&ctx->part->parent->body_size, &ctx->part->header_size);
+ ctx->part->parent->children_count += 1 + ctx->part->children_count;
ctx->part = ctx->part->parent;
}
--
2.11.0
@@ -0,0 +1,88 @@
From 99ee7596712cf0ea0a288b712bc898ecb2b35f9b Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 12:00:38 +0300
Subject: [PATCH 04/13] lib-mail: message-parser - Optimize appending new part
to linked list
---
src/lib-mail/message-parser.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
-#include "buffer.h"
+#include "array.h"
#include "str.h"
#include "istream.h"
#include "rfc822-parser.h"
@@ -34,6 +34,9 @@ struct message_parser_ctx {
const char *last_boundary;
struct message_boundary *boundaries;
+ struct message_part **next_part;
+ ARRAY(struct message_part **) next_part_stack;
+
size_t skip;
char last_chr;
unsigned int want_count;
@@ -171,7 +174,7 @@ static void
message_part_append(struct message_parser_ctx *ctx)
{
struct message_part *parent = ctx->part;
- struct message_part *part, **list;
+ struct message_part *part;
i_assert(parent != NULL);
i_assert((parent->flags & (MESSAGE_PART_FLAG_MULTIPART |
@@ -186,16 +189,27 @@ message_part_append(struct message_parse
parent->body_size.physical_size +
parent->header_size.physical_size;
- list = &part->parent->children;
- while (*list != NULL)
- list = &(*list)->next;
+ /* add to parent's linked list */
+ *ctx->next_part = part;
+ /* update the parent's end-of-linked-list pointer */
+ struct message_part **next_part = &part->next;
+ array_append(&ctx->next_part_stack, &next_part, 1);
+ /* This part is now the new parent for the next message_part_append()
+ call. Its linked list begins with the children pointer. */
+ ctx->next_part = &part->children;
- *list = part;
ctx->part = part;
}
static void message_part_finish(struct message_parser_ctx *ctx)
{
+ struct message_part **const *parent_next_partp;
+ unsigned int count = array_count(&ctx->next_part_stack);
+
+ parent_next_partp = array_idx(&ctx->next_part_stack, count-1);
+ array_delete(&ctx->next_part_stack, count-1, 1);
+ ctx->next_part = *parent_next_partp;
+
message_size_add(&ctx->part->parent->body_size, &ctx->part->body_size);
message_size_add(&ctx->part->parent->body_size, &ctx->part->header_size);
ctx->part->parent->children_count += 1 + ctx->part->children_count;
@@ -1062,7 +1076,9 @@ message_parser_init(pool_t part_pool, st
ctx = message_parser_init_int(input, hdr_flags, flags);
ctx->part_pool = part_pool;
ctx->parts = ctx->part = p_new(part_pool, struct message_part, 1);
+ ctx->next_part = &ctx->part->children;
ctx->parse_next_block = parse_next_header_init;
+ p_array_init(&ctx->next_part_stack, ctx->parser_pool, 4);
return ctx;
}
@@ -0,0 +1,45 @@
From e39c95b248917eb2b596ca55a957f3cbc7fd406f Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 12:10:07 +0300
Subject: [PATCH 05/13] lib-mail: message-parser - Minor code cleanup to
finding the end of boundary line
---
src/lib-mail/message-parser.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index ff4e09e5a..6c6a680b5 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -260,17 +260,16 @@ boundary_line_find(struct message_parser_ctx *ctx,
}
/* need to find the end of line */
- if (memchr(data + 2, '\n', size - 2) == NULL &&
- size < BOUNDARY_END_MAX_LEN &&
+ data += 2;
+ size -= 2;
+ if (memchr(data, '\n', size) == NULL &&
+ size+2 < BOUNDARY_END_MAX_LEN &&
!ctx->input->eof && !full) {
/* no LF found */
ctx->want_count = BOUNDARY_END_MAX_LEN;
return 0;
}
- data += 2;
- size -= 2;
-
*boundary_r = boundary_find(ctx->boundaries, data, size);
if (*boundary_r == NULL)
return -1;
--
2.11.0
@@ -0,0 +1,163 @@
From aed125484a346b4893c1a169088c39fe7ced01f3 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 12:53:12 +0300
Subject: [PATCH 06/13] lib-mail: message-parser - Truncate excessively long
MIME boundaries
RFC 2046 requires that the boundaries are a maximum of 70 characters
(excluding the "--" prefix and suffix). We allow 80 characters for a bit of
extra safety. Anything longer than that is truncated and treated the same
as if it was just 80 characters.
---
src/lib-mail/message-parser.c | 7 ++-
src/lib-mail/test-message-parser.c | 95 ++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+), 2 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index 6c6a680b5..92f541b02 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -10,7 +10,8 @@
/* RFC-2046 requires boundaries are max. 70 chars + "--" prefix + "--" suffix.
We'll add a bit more just in case. */
-#define BOUNDARY_END_MAX_LEN (70 + 2 + 2 + 10)
+#define BOUNDARY_STRING_MAX_LEN (70 + 10)
+#define BOUNDARY_END_MAX_LEN (BOUNDARY_STRING_MAX_LEN + 2 + 2)
struct message_boundary {
struct message_boundary *next;
@@ -526,8 +527,10 @@ static void parse_content_type(struct message_parser_ctx *ctx,
rfc2231_parse(&parser, &results);
for (; *results != NULL; results += 2) {
if (strcasecmp(results[0], "boundary") == 0) {
+ /* truncate excessively long boundaries */
ctx->last_boundary =
- p_strdup(ctx->parser_pool, results[1]);
+ p_strndup(ctx->parser_pool, results[1],
+ BOUNDARY_STRING_MAX_LEN);
break;
}
}
diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c
index 1f1aa1437..94aa3eb7c 100644
--- a/src/lib-mail/test-message-parser.c
+++ b/src/lib-mail/test-message-parser.c
@@ -642,6 +642,100 @@ static void test_message_parser_no_eoh(void)
test_end();
}
+static void test_message_parser_long_mime_boundary(void)
+{
+ /* Close the boundaries in wrong reverse order. But because all
+ boundaries are actually truncated to the same size (..890) it
+ works the same as if all of them were duplicate boundaries. */
+static const char input_msg[] =
+"Content-Type: multipart/mixed; boundary=\"1234567890123456789012345678901234567890123456789012345678901234567890123456789012\"\n"
+"\n"
+"--1234567890123456789012345678901234567890123456789012345678901234567890123456789012\n"
+"Content-Type: multipart/mixed; boundary=\"123456789012345678901234567890123456789012345678901234567890123456789012345678901\"\n"
+"\n"
+"--123456789012345678901234567890123456789012345678901234567890123456789012345678901\n"
+"Content-Type: multipart/mixed; boundary=\"12345678901234567890123456789012345678901234567890123456789012345678901234567890\"\n"
+"\n"
+"--12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
+"Content-Type: text/plain\n"
+"\n"
+"1\n"
+"--1234567890123456789012345678901234567890123456789012345678901234567890123456789012\n"
+"Content-Type: text/plain\n"
+"\n"
+"22\n"
+"--123456789012345678901234567890123456789012345678901234567890123456789012345678901\n"
+"Content-Type: text/plain\n"
+"\n"
+"333\n"
+"--12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
+"Content-Type: text/plain\n"
+"\n"
+"4444\n";
+ struct message_parser_ctx *parser;
+ struct istream *input;
+ struct message_part *parts, *part;
+ struct message_block block;
+ pool_t pool;
+ int ret;
+
+ test_begin("message parser long mime boundary");
+ pool = pool_alloconly_create("message parser", 10240);
+ input = test_istream_create(input_msg);
+
+ parser = message_parser_init(pool, input, 0, 0);
+ while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
+ test_assert(ret < 0);
+ message_parser_deinit(&parser, &parts);
+
+ part = parts;
+ test_assert(part->children_count == 6);
+ test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
+ test_assert(part->header_size.lines == 2);
+ test_assert(part->header_size.physical_size == 126);
+ test_assert(part->header_size.virtual_size == 126+2);
+ test_assert(part->body_size.lines == 22);
+ test_assert(part->body_size.physical_size == 871);
+ test_assert(part->body_size.virtual_size == 871+22);
+
+ part = parts->children;
+ test_assert(part->children_count == 5);
+ test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
+ test_assert(part->header_size.lines == 2);
+ test_assert(part->header_size.physical_size == 125);
+ test_assert(part->header_size.virtual_size == 125+2);
+ test_assert(part->body_size.lines == 19);
+ test_assert(part->body_size.physical_size == 661);
+ test_assert(part->body_size.virtual_size == 661+19);
+
+ part = parts->children->children;
+ test_assert(part->children_count == 4);
+ test_assert(part->flags == (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_IS_MIME));
+ test_assert(part->header_size.lines == 2);
+ test_assert(part->header_size.physical_size == 124);
+ test_assert(part->header_size.virtual_size == 124+2);
+ test_assert(part->body_size.lines == 16);
+ test_assert(part->body_size.physical_size == 453);
+ test_assert(part->body_size.virtual_size == 453+16);
+
+ part = parts->children->children->children;
+ for (unsigned int i = 1; i <= 3; i++, part = part->next) {
+ test_assert(part->children_count == 0);
+ test_assert(part->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME));
+ test_assert(part->header_size.lines == 2);
+ test_assert(part->header_size.physical_size == 26);
+ test_assert(part->header_size.virtual_size == 26+2);
+ test_assert(part->body_size.lines == 0);
+ test_assert(part->body_size.physical_size == i);
+ test_assert(part->body_size.virtual_size == i);
+ }
+
+ test_parsed_parts(input, parts);
+ i_stream_unref(&input);
+ pool_unref(&pool);
+ test_end();
+}
+
int main(void)
{
static void (*test_functions[])(void) = {
@@ -654,6 +748,7 @@ int main(void)
test_message_parser_garbage_suffix_mime_boundary,
test_message_parser_continuing_mime_boundary,
test_message_parser_continuing_truncated_mime_boundary,
+ test_message_parser_long_mime_boundary,
test_message_parser_no_eoh,
NULL
};
--
2.11.0
@@ -0,0 +1,72 @@
From 5f8de52fec3191a1aa68a399ee2068485737dc4f Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 13:06:02 +0300
Subject: [PATCH 07/13] lib-mail: message-parser - Optimize boundary lookups
when exact boundary is found
When an exact boundary is found, there's no need to continue looking for
more boundaries.
---
src/lib-mail/message-parser.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index 92f541b02..c2934c761 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -80,8 +80,14 @@ boundary_find(struct message_boundary *boundaries,
while (boundaries != NULL) {
if (boundaries->len <= len &&
memcmp(boundaries->boundary, data, boundaries->len) == 0 &&
- (best == NULL || best->len < boundaries->len))
+ (best == NULL || best->len < boundaries->len)) {
best = boundaries;
+ if (best->len == len) {
+ /* This is exactly the wanted boundary. There
+ can't be a better one. */
+ break;
+ }
+ }
boundaries = boundaries->next;
}
@@ -263,15 +269,27 @@ boundary_line_find(struct message_parser_ctx *ctx,
/* need to find the end of line */
data += 2;
size -= 2;
- if (memchr(data, '\n', size) == NULL &&
+ const unsigned char *lf_pos = memchr(data, '\n', size);
+ if (lf_pos == NULL &&
size+2 < BOUNDARY_END_MAX_LEN &&
!ctx->input->eof && !full) {
/* no LF found */
ctx->want_count = BOUNDARY_END_MAX_LEN;
return 0;
}
-
- *boundary_r = boundary_find(ctx->boundaries, data, size);
+ size_t find_size = size;
+
+ if (lf_pos != NULL) {
+ find_size = lf_pos - data;
+ if (find_size > 0 && data[find_size-1] == '\r')
+ find_size--;
+ if (find_size > 2 && data[find_size-1] == '-' &&
+ data[find_size-2] == '-')
+ find_size -= 2;
+ } else if (find_size > BOUNDARY_END_MAX_LEN)
+ find_size = BOUNDARY_END_MAX_LEN;
+
+ *boundary_r = boundary_find(ctx->boundaries, data, find_size);
if (*boundary_r == NULL)
return -1;
--
2.11.0
@@ -0,0 +1,50 @@
From 929396767d831bedbdec6392aaa835b045332fd3 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 14:53:27 +0300
Subject: [PATCH 08/13] lib-mail: message-parser - Add boundary_remove_until()
helper function
---
src/lib-mail/message-parser.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index c2934c761..028f74159 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -223,6 +223,13 @@ static void message_part_finish(struct message_parser_ctx *ctx)
ctx->part = ctx->part->parent;
}
+static void
+boundary_remove_until(struct message_parser_ctx *ctx,
+ struct message_boundary *boundary)
+{
+ ctx->boundaries = boundary;
+}
+
static void parse_next_body_multipart_init(struct message_parser_ctx *ctx)
{
struct message_boundary *b;
@@ -364,10 +371,10 @@ static int parse_part_finish(struct message_parser_ctx *ctx,
if (boundary->epilogue_found) {
/* this boundary isn't needed anymore */
- ctx->boundaries = boundary->next;
+ boundary_remove_until(ctx, boundary->next);
} else {
/* forget about the boundaries we possibly skipped */
- ctx->boundaries = boundary;
+ boundary_remove_until(ctx, boundary);
}
/* the boundary itself should already be in buffer. add that. */
--
2.11.0
@@ -0,0 +1,169 @@
From d53d83214b1d635446a8cf8ff9438cc530133d62 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 15:00:57 +0300
Subject: [PATCH 09/13] lib-mail: message-parser - Don't use memory pool for
parser
This reduces memory usage when parsing many MIME parts where boundaries are
being added and removed constantly.
---
src/lib-mail/message-parser.c | 48 ++++++++++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 16 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index 028f74159..8970d8e0e 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -17,14 +17,14 @@ struct message_boundary {
struct message_boundary *next;
struct message_part *part;
- const char *boundary;
+ char *boundary;
size_t len;
unsigned int epilogue_found:1;
};
struct message_parser_ctx {
- pool_t parser_pool, part_pool;
+ pool_t part_pool;
struct istream *input;
struct message_part *parts, *part;
const char *broken_reason;
@@ -32,7 +32,7 @@ struct message_parser_ctx {
enum message_header_parser_flags hdr_flags;
enum message_parser_flags flags;
- const char *last_boundary;
+ char *last_boundary;
struct message_boundary *boundaries;
struct message_part **next_part;
@@ -223,10 +223,24 @@ static void message_part_finish(struct message_parser_ctx *ctx)
ctx->part = ctx->part->parent;
}
+static void message_boundary_free(struct message_boundary *b)
+{
+ i_free(b->boundary);
+ i_free(b);
+}
+
static void
boundary_remove_until(struct message_parser_ctx *ctx,
struct message_boundary *boundary)
{
+ while (ctx->boundaries != boundary) {
+ struct message_boundary *cur = ctx->boundaries;
+
+ i_assert(cur != NULL);
+ ctx->boundaries = cur->next;
+ message_boundary_free(cur);
+
+ }
ctx->boundaries = boundary;
}
@@ -234,15 +248,14 @@ static void parse_next_body_multipart_init(struct message_parser_ctx *ctx)
{
struct message_boundary *b;
- b = p_new(ctx->parser_pool, struct message_boundary, 1);
+ b = i_new(struct message_boundary, 1);
b->part = ctx->part;
b->boundary = ctx->last_boundary;
+ ctx->last_boundary = NULL;
b->len = strlen(b->boundary);
b->next = ctx->boundaries;
ctx->boundaries = b;
-
- ctx->last_boundary = NULL;
}
static int parse_next_body_message_rfc822_init(struct message_parser_ctx *ctx,
@@ -359,6 +372,8 @@ static int parse_part_finish(struct message_parser_ctx *ctx,
struct message_block *block_r, bool first_line)
{
size_t line_size;
+ size_t boundary_len = boundary->len;
+ bool boundary_epilogue_found = boundary->epilogue_found;
i_assert(ctx->last_boundary == NULL);
@@ -391,7 +406,7 @@ static int parse_part_finish(struct message_parser_ctx *ctx,
i_assert(block_r->data[0] == '\n');
line_size = 1;
}
- line_size += 2 + boundary->len + (boundary->epilogue_found ? 2 : 0);
+ line_size += 2 + boundary_len + (boundary_epilogue_found ? 2 : 0);
i_assert(block_r->size >= ctx->skip + line_size);
block_r->size = line_size;
parse_body_add_block(ctx, block_r);
@@ -553,9 +568,9 @@ static void parse_content_type(struct message_parser_ctx *ctx,
for (; *results != NULL; results += 2) {
if (strcasecmp(results[0], "boundary") == 0) {
/* truncate excessively long boundaries */
+ i_free(ctx->last_boundary);
ctx->last_boundary =
- p_strndup(ctx->parser_pool, results[1],
- BOUNDARY_STRING_MAX_LEN);
+ i_strndup(results[1], BOUNDARY_STRING_MAX_LEN);
break;
}
}
@@ -678,7 +693,7 @@ static int parse_next_header(struct message_parser_ctx *ctx,
i_assert(!ctx->multipart);
part->flags = 0;
}
- ctx->last_boundary = NULL;
+ i_free(ctx->last_boundary);
if (!ctx->part_seen_content_type ||
(part->flags & MESSAGE_PART_FLAG_IS_MIME) == 0) {
@@ -1081,11 +1096,8 @@ message_parser_init_int(struct istream *input,
enum message_parser_flags flags)
{
struct message_parser_ctx *ctx;
- pool_t pool;
- pool = pool_alloconly_create("Message Parser", 1024);
- ctx = p_new(pool, struct message_parser_ctx, 1);
- ctx->parser_pool = pool;
+ ctx = i_new(struct message_parser_ctx, 1);
ctx->hdr_flags = hdr_flags;
ctx->flags = flags;
ctx->input = input;
@@ -1105,7 +1117,7 @@ message_parser_init(pool_t part_pool, struct istream *input,
ctx->parts = ctx->part = p_new(part_pool, struct message_part, 1);
ctx->next_part = &ctx->part->children;
ctx->parse_next_block = parse_next_header_init;
- p_array_init(&ctx->next_part_stack, ctx->parser_pool, 4);
+ i_array_init(&ctx->next_part_stack, 4);
return ctx;
}
@@ -1146,8 +1158,12 @@ int message_parser_deinit_from_parts(struct message_parser_ctx **_ctx,
if (ctx->hdr_parser_ctx != NULL)
message_parse_header_deinit(&ctx->hdr_parser_ctx);
+ boundary_remove_until(ctx, NULL);
i_stream_unref(&ctx->input);
- pool_unref(&ctx->parser_pool);
+ if (array_is_created(&ctx->next_part_stack))
+ array_free(&ctx->next_part_stack);
+ i_free(ctx->last_boundary);
+ i_free(ctx);
i_assert(ret < 0 || *parts_r != NULL);
return ret;
}
--
2.11.0
@@ -0,0 +1,188 @@
From df9e0d358ef86e3342525dcdefcf79dc2d749a30 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 16:59:40 +0300
Subject: [PATCH 10/13] lib-mail: message-parser - Support limiting max number
of nested MIME parts
The default is to allow 100 nested MIME parts. When the limit is reached,
the innermost MIME part's body contains all the rest of the inner bodies
until a parent MIME part is reached.
---
src/lib-mail/message-parser.c | 43 +++++++++++++++++++++++++++++++-------
src/lib-mail/test-message-parser.c | 31 +++++++++++++++++++++++++++
2 files changed, 67 insertions(+), 7 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index 8970d8e0e..721615f76 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -13,6 +13,8 @@
#define BOUNDARY_STRING_MAX_LEN (70 + 10)
#define BOUNDARY_END_MAX_LEN (BOUNDARY_STRING_MAX_LEN + 2 + 2)
+#define MESSAGE_PARSER_DEFAULT_MAX_NESTED_MIME_PARTS 100
+
struct message_boundary {
struct message_boundary *next;
@@ -28,9 +30,11 @@ struct message_parser_ctx {
struct istream *input;
struct message_part *parts, *part;
const char *broken_reason;
+ unsigned int nested_parts_count;
enum message_header_parser_flags hdr_flags;
enum message_parser_flags flags;
+ unsigned int max_nested_mime_parts;
char *last_boundary;
struct message_boundary *boundaries;
@@ -206,6 +210,8 @@ message_part_append(struct message_parser_ctx *ctx)
ctx->next_part = &part->children;
ctx->part = part;
+ ctx->nested_parts_count++;
+ i_assert(ctx->nested_parts_count < ctx->max_nested_mime_parts);
}
static void message_part_finish(struct message_parser_ctx *ctx)
@@ -213,8 +219,12 @@ static void message_part_finish(struct message_parser_ctx *ctx)
struct message_part **const *parent_next_partp;
unsigned int count = array_count(&ctx->next_part_stack);
+ i_assert(ctx->nested_parts_count > 0);
+ ctx->nested_parts_count--;
+
parent_next_partp = array_idx(&ctx->next_part_stack, count-1);
array_delete(&ctx->next_part_stack, count-1, 1);
+
ctx->next_part = *parent_next_partp;
message_size_add(&ctx->part->parent->body_size, &ctx->part->body_size);
@@ -592,6 +602,11 @@ static bool block_is_at_eoh(const struct message_block *block)
return FALSE;
}
+static bool parse_too_many_nested_mime_parts(struct message_parser_ctx *ctx)
+{
+ return ctx->nested_parts_count > ctx->max_nested_mime_parts;
+}
+
#define MUTEX_FLAGS \
(MESSAGE_PART_FLAG_MESSAGE_RFC822 | MESSAGE_PART_FLAG_MULTIPART)
@@ -616,8 +631,12 @@ static int parse_next_header(struct message_parser_ctx *ctx,
"\n--boundary" belongs to us or to a previous boundary.
this is a problem if the boundary prefixes are identical,
because MIME requires only the prefix to match. */
- parse_next_body_multipart_init(ctx);
- ctx->multipart = TRUE;
+ if (!parse_too_many_nested_mime_parts(ctx)) {
+ parse_next_body_multipart_init(ctx);
+ ctx->multipart = TRUE;
+ } else {
+ part->flags &= ~MESSAGE_PART_FLAG_MULTIPART;
+ }
}
/* before parsing the header see if we can find a --boundary from here.
@@ -721,12 +740,16 @@ static int parse_next_header(struct message_parser_ctx *ctx,
i_assert(ctx->last_boundary == NULL);
ctx->multipart = FALSE;
ctx->parse_next_block = parse_next_body_to_boundary;
- } else if (part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822)
+ } else if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0 &&
+ !parse_too_many_nested_mime_parts(ctx)) {
ctx->parse_next_block = parse_next_body_message_rfc822_init;
- else if (ctx->boundaries != NULL)
- ctx->parse_next_block = parse_next_body_to_boundary;
- else
- ctx->parse_next_block = parse_next_body_to_eof;
+ } else {
+ part->flags &= ~MESSAGE_PART_FLAG_MESSAGE_RFC822;
+ if (ctx->boundaries != NULL)
+ ctx->parse_next_block = parse_next_body_to_boundary;
+ else
+ ctx->parse_next_block = parse_next_body_to_eof;
+ }
ctx->want_count = 1;
@@ -1100,6 +1123,8 @@ message_parser_init_int(struct istream *input,
ctx = i_new(struct message_parser_ctx, 1);
ctx->hdr_flags = hdr_flags;
ctx->flags = flags;
+ ctx->max_nested_mime_parts =
+ MESSAGE_PARSER_DEFAULT_MAX_NESTED_MIME_PARTS;
ctx->input = input;
i_stream_ref(input);
return ctx;
@@ -1159,6 +1184,10 @@ int message_parser_deinit_from_parts(struct message_parser_ctx **_ctx,
if (ctx->hdr_parser_ctx != NULL)
message_parse_header_deinit(&ctx->hdr_parser_ctx);
boundary_remove_until(ctx, NULL);
+ /* caller might have stopped the parsing early */
+ i_assert(ctx->nested_parts_count == 0 ||
+ i_stream_have_bytes_left(ctx->input));
+
i_stream_unref(&ctx->input);
if (array_is_created(&ctx->next_part_stack))
array_free(&ctx->next_part_stack);
diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c
index 94aa3eb7c..481d05942 100644
--- a/src/lib-mail/test-message-parser.c
+++ b/src/lib-mail/test-message-parser.c
@@ -166,6 +166,36 @@ static void test_message_parser_small_blocks(void)
test_end();
}
+static void test_message_parser_stop_early(void)
+{
+ struct message_parser_ctx *parser;
+ struct istream *input;
+ struct message_part *parts;
+ struct message_block block;
+ unsigned int i;
+ pool_t pool;
+ int ret;
+
+ test_begin("message parser stop early");
+ pool = pool_alloconly_create("message parser", 10240);
+ input = test_istream_create(test_msg);
+
+ test_istream_set_allow_eof(input, FALSE);
+ for (i = 1; i <= TEST_MSG_LEN+1; i++) {
+ i_stream_seek(input, 0);
+ test_istream_set_size(input, i);
+ parser = message_parser_init(pool, input, 0, 0);
+ while ((ret = message_parser_parse_next_block(parser,
+ &block)) > 0) ;
+ test_assert(ret == 0);
+ message_parser_deinit(&parser, &parts);
+ }
+
+ i_stream_unref(&input);
+ pool_unref(&pool);
+ test_end();
+}
+
static void test_message_parser_truncated_mime_headers(void)
{
static const char input_msg[] =
@@ -740,6 +770,7 @@ int main(void)
{
static void (*test_functions[])(void) = {
test_message_parser_small_blocks,
+ test_message_parser_stop_early,
test_message_parser_truncated_mime_headers,
test_message_parser_truncated_mime_headers2,
test_message_parser_truncated_mime_headers3,
--
2.11.0
@@ -0,0 +1,87 @@
From d7bba401dd234802bcdb55ff27dfb99bffdab804 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 23 Apr 2020 17:09:33 +0300
Subject: [PATCH 11/13] lib-mail: message-parser - Support limiting max number
of MIME parts
The default is to allow 10000 MIME parts. When it's reached, no more
MIME boundary lines will be recognized, so the rest of the mail belongs
to the last added MIME part.
---
src/lib-mail/message-parser.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index 721615f76..646307802 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -14,6 +14,7 @@
#define BOUNDARY_END_MAX_LEN (BOUNDARY_STRING_MAX_LEN + 2 + 2)
#define MESSAGE_PARSER_DEFAULT_MAX_NESTED_MIME_PARTS 100
+#define MESSAGE_PARSER_DEFAULT_MAX_TOTAL_MIME_PARTS 10000
struct message_boundary {
struct message_boundary *next;
@@ -31,10 +32,12 @@ struct message_parser_ctx {
struct message_part *parts, *part;
const char *broken_reason;
unsigned int nested_parts_count;
+ unsigned int total_parts_count;
enum message_header_parser_flags hdr_flags;
enum message_parser_flags flags;
unsigned int max_nested_mime_parts;
+ unsigned int max_total_mime_parts;
char *last_boundary;
struct message_boundary *boundaries;
@@ -211,7 +214,9 @@ message_part_append(struct message_parser_ctx *ctx)
ctx->part = part;
ctx->nested_parts_count++;
+ ctx->total_parts_count++;
i_assert(ctx->nested_parts_count < ctx->max_nested_mime_parts);
+ i_assert(ctx->total_parts_count <= ctx->max_total_mime_parts);
}
static void message_part_finish(struct message_parser_ctx *ctx)
@@ -296,6 +301,12 @@ boundary_line_find(struct message_parser_ctx *ctx,
return -1;
}
+ if (ctx->total_parts_count >= ctx->max_total_mime_parts) {
+ /* can't add any more MIME parts. just stop trying to find
+ more boundaries. */
+ return -1;
+ }
+
/* need to find the end of line */
data += 2;
size -= 2;
@@ -1125,6 +1136,8 @@ message_parser_init_int(struct istream *input,
ctx->flags = flags;
ctx->max_nested_mime_parts =
MESSAGE_PARSER_DEFAULT_MAX_NESTED_MIME_PARTS;
+ ctx->max_total_mime_parts =
+ MESSAGE_PARSER_DEFAULT_MAX_TOTAL_MIME_PARTS;
ctx->input = input;
i_stream_ref(input);
return ctx;
@@ -1142,6 +1155,7 @@ message_parser_init(pool_t part_pool, struct istream *input,
ctx->parts = ctx->part = p_new(part_pool, struct message_part, 1);
ctx->next_part = &ctx->part->children;
ctx->parse_next_block = parse_next_header_init;
+ ctx->total_parts_count = 1;
i_array_init(&ctx->next_part_stack, 4);
return ctx;
}
--
2.11.0
@@ -0,0 +1,133 @@
From 0c9d56b41b992a868f299e05677a67c4d0495523 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 2 Jul 2020 17:31:19 +0300
Subject: [PATCH 12/13] lib-mail: Fix handling trailing "--" in MIME boundaries
Broken by 5b8ec27fae941d06516c30476dcf4820c6d200ab
---
src/lib-mail/message-parser.c | 14 ++++++++----
src/lib-mail/test-message-parser.c | 46 ++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 4 deletions(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index 646307802..175d4b488 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -75,7 +75,7 @@ static int preparsed_parse_next_header_init(struct message_parser_ctx *ctx,
static struct message_boundary *
boundary_find(struct message_boundary *boundaries,
- const unsigned char *data, size_t len)
+ const unsigned char *data, size_t len, bool trailing_dashes)
{
struct message_boundary *best = NULL;
@@ -89,7 +89,11 @@ boundary_find(struct message_boundary *boundaries,
memcmp(boundaries->boundary, data, boundaries->len) == 0 &&
(best == NULL || best->len < boundaries->len)) {
best = boundaries;
- if (best->len == len) {
+ /* If we see "foo--", it could either mean that there
+ is a boundary named "foo" that ends now or there's
+ a boundary "foo--" which continues. */
+ if (best->len == len ||
+ (best->len == len-2 && trailing_dashes)) {
/* This is exactly the wanted boundary. There
can't be a better one. */
break;
@@ -319,6 +323,7 @@ boundary_line_find(struct message_parser_ctx *ctx,
return 0;
}
size_t find_size = size;
+ bool trailing_dashes = FALSE;
if (lf_pos != NULL) {
find_size = lf_pos - data;
@@ -326,11 +331,12 @@ boundary_line_find(struct message_parser_ctx *ctx,
find_size--;
if (find_size > 2 && data[find_size-1] == '-' &&
data[find_size-2] == '-')
- find_size -= 2;
+ trailing_dashes = TRUE;
} else if (find_size > BOUNDARY_END_MAX_LEN)
find_size = BOUNDARY_END_MAX_LEN;
- *boundary_r = boundary_find(ctx->boundaries, data, find_size);
+ *boundary_r = boundary_find(ctx->boundaries, data, find_size,
+ trailing_dashes);
if (*boundary_r == NULL)
return -1;
diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c
index 481d05942..113454ea0 100644
--- a/src/lib-mail/test-message-parser.c
+++ b/src/lib-mail/test-message-parser.c
@@ -510,6 +510,51 @@ static const char input_msg[] =
test_end();
}
+static void test_message_parser_trailing_dashes(void)
+{
+static const char input_msg[] =
+"Content-Type: multipart/mixed; boundary=\"a--\"\n"
+"\n"
+"--a--\n"
+"Content-Type: multipart/mixed; boundary=\"a----\"\n"
+"\n"
+"--a----\n"
+"Content-Type: text/plain\n"
+"\n"
+"body\n"
+"--a------\n"
+"Content-Type: text/html\n"
+"\n"
+"body2\n"
+"--a----";
+ struct message_parser_ctx *parser;
+ struct istream *input;
+ struct message_part *parts;
+ struct message_block block;
+ pool_t pool;
+ int ret;
+
+ test_begin("message parser trailing dashes");
+ pool = pool_alloconly_create("message parser", 10240);
+ input = test_istream_create(input_msg);
+
+ parser = message_parser_init(pool, input, 0, 0);
+ while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
+ test_assert(ret < 0);
+ message_parser_deinit(&parser, &parts);
+
+ test_assert(parts->children_count == 2);
+ test_assert(parts->children->next == NULL);
+ test_assert(parts->children->children_count == 1);
+ test_assert(parts->children->children->next == NULL);
+ test_assert(parts->children->children->children_count == 0);
+
+ test_parsed_parts(input, parts);
+ i_stream_unref(&input);
+ pool_unref(&pool);
+ test_end();
+}
+
static void test_message_parser_continuing_mime_boundary(void)
{
static const char input_msg[] =
@@ -777,6 +822,7 @@ int main(void)
test_message_parser_empty_multipart,
test_message_parser_duplicate_mime_boundary,
test_message_parser_garbage_suffix_mime_boundary,
+ test_message_parser_trailing_dashes,
test_message_parser_continuing_mime_boundary,
test_message_parser_continuing_truncated_mime_boundary,
test_message_parser_long_mime_boundary,
--
2.11.0
@@ -0,0 +1,32 @@
From f77a2b6c3ffe2ea96f4a4b05ec38dc9d53266ecb Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Wed, 27 May 2020 11:35:55 +0300
Subject: [PATCH 13/13] lib-mail: Fix parse_too_many_nested_mime_parts()
This was originally correct, until it was "optimized" wrong and got merged.
---
src/lib-mail/message-parser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c
index 175d4b488..5b11772ff 100644
--- a/src/lib-mail/message-parser.c
+++ b/src/lib-mail/message-parser.c
@@ -621,7 +621,7 @@ static bool block_is_at_eoh(const struct message_block *block)
static bool parse_too_many_nested_mime_parts(struct message_parser_ctx *ctx)
{
- return ctx->nested_parts_count > ctx->max_nested_mime_parts;
+ return ctx->nested_parts_count+1 >= ctx->max_nested_mime_parts;
}
#define MUTEX_FLAGS \
--
2.11.0
@@ -0,0 +1,27 @@
From 1a6ff0beebf0ab0c71081eaff1d5d7fd26015a94 Mon Sep 17 00:00:00 2001
From: Josef 'Jeff' Sipek <jeff.sipek@dovecot.fi>
Date: Tue, 19 Sep 2017 13:26:57 +0300
Subject: [PATCH] lib: buffer_free(NULL) should be a no-op
---
src/lib/buffer.c | 3 +++
1 file changed, 3 insertions(+)
Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com>
CVE: CVE-2020-12100
Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/d/dovecot/dovecot_2.2.33.2-1ubuntu4.7.debian.tar.xz]
Comment: No change in any hunk
--- a/src/lib/buffer.c
+++ b/src/lib/buffer.c
@@ -148,6 +148,9 @@ void buffer_free(buffer_t **_buf)
{
struct real_buffer *buf = (struct real_buffer *)*_buf;
+ if (buf == NULL)
+ return;
+
*_buf = NULL;
if (buf->alloced)
p_free(buf->pool, buf->w_buffer);
@@ -10,6 +10,20 @@ SRC_URI = "http://dovecot.org/releases/2.2/dovecot-${PV}.tar.gz \
file://dovecot.service \
file://dovecot.socket \
file://0001-doveadm-Fix-parallel-build.patch \
file://0001-lib-mail-message-parser-Add-a-message_part_finish-he.patch \
file://0002-lib-mail-message-parser-Change-message_part_append-t.patch \
file://0003-lib-mail-message-parser-Optimize-updating-children_c.patch \
file://0004-lib-mail-message-parser-Optimize-appending-new-part-.patch \
file://0005-lib-mail-message-parser-Minor-code-cleanup-to-findin.patch \
file://0006-lib-mail-message-parser-Truncate-excessively-long-MI.patch \
file://0007-lib-mail-message-parser-Optimize-boundary-lookups-wh.patch \
file://0008-lib-mail-message-parser-Add-boundary_remove_until-he.patch \
file://0009-lib-mail-message-parser-Don-t-use-memory-pool-for-pa.patch \
file://0010-lib-mail-message-parser-Support-limiting-max-number-.patch \
file://0011-lib-mail-message-parser-Support-limiting-max-number-.patch \
file://0012-lib-mail-Fix-handling-trailing-in-MIME-boundaries.patch \
file://0013-lib-mail-Fix-parse_too_many_nested_mime_parts.patch \
file://buffer_free_fix.patch \
"
SRC_URI[md5sum] = "66c4d71858b214afee5b390ee602dee2"