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