diff options
author | sana kazi <sanakazisk19@gmail.com> | 2021-12-03 17:57:19 +0530 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2021-12-03 12:23:33 -0800 |
commit | 00ad99f4f9a06d66bd5686d2b1dd07c578c8dc2a (patch) | |
tree | a809ba1c690bd15d55625d725624ebe2b11b1603 | |
parent | e0e79bbde23f17185cc59908fee97c0cea098428 (diff) | |
download | meta-openembedded-00ad99f4f9a06d66bd5686d2b1dd07c578c8dc2a.tar.gz |
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>
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 000000000..583f71ca5 --- /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 000000000..9f24320eb --- /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 000000000..e53090235 --- /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 000000000..c35bf883e --- /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 000000000..4e63509b4 --- /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 000000000..1012d7983 --- /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 000000000..eeb6c96f1 --- /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 000000000..4af070a87 --- /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 000000000..aade7dc2b --- /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 000000000..ae5254466 --- /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 000000000..52848bf3a --- /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 000000000..a81177d2b --- /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 000000000..97068345f --- /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 000000000..44f6564f8 --- /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 e21a94ad6..407604c81 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" |