diff -Nru dovecot-2.2.27/debian/changelog dovecot-2.2.27/debian/changelog --- dovecot-2.2.27/debian/changelog 2018-01-31 16:38:11.000000000 +0000 +++ dovecot-2.2.27/debian/changelog 2018-02-26 18:19:51.000000000 +0000 @@ -1,3 +1,15 @@ +dovecot (1:2.2.27-3ubuntu1.3) artful-security; urgency=medium + + * SECURITY UPDATE: rfc822_parse_domain Information Leak Vulnerability + - debian/patches/CVE-2017-14461/*.patch: upstream parsing fixes. + - CVE-2017-14461 + * SECURITY UPDATE: TLS SNI config lookups DoS + - debian/patches/CVE-2017-15130/*.patch: upstream config filtering fix. + - CVE-2017-15130 + * debian/rules: create m4 directory and run autoreconf. + + -- Marc Deslauriers Mon, 26 Feb 2018 13:19:51 -0500 + dovecot (1:2.2.27-3ubuntu1.2) artful-security; urgency=medium * SECURITY UPDATE: Memory leak that can cause crash due to memory exhaustion diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-14461/0001-lib-mail-rfc822-parser-Add-asserts-to-make-sure-pars.patch dovecot-2.2.27/debian/patches/CVE-2017-14461/0001-lib-mail-rfc822-parser-Add-asserts-to-make-sure-pars.patch --- dovecot-2.2.27/debian/patches/CVE-2017-14461/0001-lib-mail-rfc822-parser-Add-asserts-to-make-sure-pars.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-14461/0001-lib-mail-rfc822-parser-Add-asserts-to-make-sure-pars.patch 2018-02-26 17:30:38.000000000 +0000 @@ -0,0 +1,41 @@ +From 30dc856f7b97b75b0e0d69f5003d5d99a13249b4 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Fri, 22 Dec 2017 18:31:52 +0200 +Subject: [PATCH 1/7] lib-mail: rfc822-parser - Add asserts to make sure parser + state is correct + +--- + src/lib-mail/rfc822-parser.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/lib-mail/rfc822-parser.c b/src/lib-mail/rfc822-parser.c +index 6dd2254..edb07f5 100644 +--- a/src/lib-mail/rfc822-parser.c ++++ b/src/lib-mail/rfc822-parser.c +@@ -211,6 +211,7 @@ int rfc822_parse_quoted_string(struct rfc822_parser_context *ctx, string_t *str) + const unsigned char *start; + size_t len; + ++ i_assert(ctx->data < ctx->end); + i_assert(*ctx->data == '"'); + ctx->data++; + +@@ -313,6 +314,7 @@ rfc822_parse_domain_literal(struct rfc822_parser_context *ctx, string_t *str) + %d94-126 ; characters not including "[", + ; "]", or "\" + */ ++ i_assert(ctx->data < ctx->end); + i_assert(*ctx->data == '['); + + for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { +@@ -338,6 +340,7 @@ int rfc822_parse_domain(struct rfc822_parser_context *ctx, string_t *str) + domain-literal = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS] + obs-domain = atom *("." atom) + */ ++ i_assert(ctx->data < ctx->end); + i_assert(*ctx->data == '@'); + ctx->data++; + +-- +2.1.4 + diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-14461/0003-lib-mail-Fix-out-of-bounds-read-when-parsing-an-inva.patch dovecot-2.2.27/debian/patches/CVE-2017-14461/0003-lib-mail-Fix-out-of-bounds-read-when-parsing-an-inva.patch --- dovecot-2.2.27/debian/patches/CVE-2017-14461/0003-lib-mail-Fix-out-of-bounds-read-when-parsing-an-inva.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-14461/0003-lib-mail-Fix-out-of-bounds-read-when-parsing-an-inva.patch 2018-02-26 18:18:44.000000000 +0000 @@ -0,0 +1,33 @@ +Backport of: + +From b72d864b8c34cb21076214c0b28101baec530141 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Fri, 22 Dec 2017 18:36:55 +0200 +Subject: [PATCH 3/7] lib-mail: Fix out-of-bounds read when parsing an invalid + email address + +The included unit test doesn't fail, but running it with valgrind shows +"Invalid read of size 1" error. + +Broken in d6737a17a27402e7a262f7ba8a2ed588d576f23c + +Discovered by Aleksandar Nikolic of Cisco Talos +--- + src/lib-mail/message-address.c | 3 ++- + src/lib-mail/test-message-address.c | 10 ++++++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +Index: dovecot-2.2.27/src/lib-mail/message-address.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-address.c 2018-02-26 12:44:32.896548544 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-address.c 2018-02-26 12:45:24.640616175 -0500 +@@ -161,7 +161,8 @@ static int parse_addr_spec(struct messag + str_truncate(ctx->parser.last_comment, 0); + + ret = parse_local_part(ctx); +- if (ret != 0 && *ctx->parser.data == '@') { ++ if (ret != 0 && ctx->parser.data != ctx->parser.end && ++ *ctx->parser.data == '@') { + ret2 = parse_domain(ctx); + if (ret2 <= 0) + ret = ret2; diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-14461/0004-lib-mail-Make-sure-parsers-don-t-accidentally-go-muc.patch dovecot-2.2.27/debian/patches/CVE-2017-14461/0004-lib-mail-Make-sure-parsers-don-t-accidentally-go-muc.patch --- dovecot-2.2.27/debian/patches/CVE-2017-14461/0004-lib-mail-Make-sure-parsers-don-t-accidentally-go-muc.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-14461/0004-lib-mail-Make-sure-parsers-don-t-accidentally-go-muc.patch 2018-02-26 18:18:57.000000000 +0000 @@ -0,0 +1,294 @@ +Backport of: + +From e9b86842441a668b30796bff7d60828614570a1b Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Fri, 22 Dec 2017 18:42:53 +0200 +Subject: [PATCH 4/7] lib-mail: Make sure parsers don't accidentally go much + beyond end pointer + +--- + src/lib-mail/message-address.c | 18 +++++++++--------- + src/lib-mail/message-date.c | 4 ++-- + src/lib-mail/message-part-data.c | 2 +- + src/lib-mail/rfc2231-parser.c | 2 +- + src/lib-mail/rfc822-parser.c | 38 +++++++++++++++++++------------------- + 5 files changed, 32 insertions(+), 32 deletions(-) + +Index: dovecot-2.2.27/src/lib-mail/message-address.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-address.c 2018-02-26 12:46:05.152669582 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-address.c 2018-02-26 13:10:51.810058343 -0500 +@@ -40,7 +40,7 @@ static int parse_local_part(struct messa + local-part = dot-atom / quoted-string / obs-local-part + obs-local-part = word *("." word) + */ +- i_assert(ctx->parser.data != ctx->parser.end); ++ i_assert(ctx->parser.data < ctx->parser.end); + + str_truncate(ctx->str, 0); + if (*ctx->parser.data == '"') +@@ -73,7 +73,7 @@ static int parse_domain_list(struct mess + /* obs-domain-list = "@" domain *(*(CFWS / "," ) [CFWS] "@" domain) */ + str_truncate(ctx->str, 0); + for (;;) { +- if (ctx->parser.data == ctx->parser.end) ++ if (ctx->parser.data >= ctx->parser.end) + return 0; + + if (*ctx->parser.data != '@') +@@ -150,7 +150,7 @@ static int parse_name_addr(struct messag + ctx->addr.domain = "SYNTAX_ERROR"; + ctx->addr.invalid_syntax = TRUE; + } +- return ctx->parser.data != ctx->parser.end; ++ return ctx->parser.data < ctx->parser.end ? 1 : 0; + } + + static int parse_addr_spec(struct message_address_parser_context *ctx) +@@ -158,10 +158,12 @@ static int parse_addr_spec(struct messag + /* addr-spec = local-part "@" domain */ + int ret, ret2; + ++ i_assert(ctx->parser.data < ctx->parser.end); ++ + str_truncate(ctx->parser.last_comment, 0); + + ret = parse_local_part(ctx); +- if (ret != 0 && ctx->parser.data != ctx->parser.end && ++ if (ret != 0 && ctx->parser.data < ctx->parser.end && + *ctx->parser.data == '@') { + ret2 = parse_domain(ctx); + if (ret2 <= 0) +@@ -237,7 +239,8 @@ static int parse_group(struct message_ad + ret = -1; + break; + } +- if (*ctx->parser.data != ',') ++ if (ctx->parser.data >= ctx->parser.end || ++ *ctx->parser.data != ',') + break; + ctx->parser.data++; + if (rfc822_skip_lwsp(&ctx->parser) <= 0) { +@@ -247,7 +250,8 @@ static int parse_group(struct message_ad + } + } + if (ret >= 0) { +- if (*ctx->parser.data != ';') ++ if (ctx->parser.data >= ctx->parser.end || ++ *ctx->parser.data != ';') + ret = -1; + else { + ctx->parser.data++; +@@ -286,7 +290,8 @@ static int parse_address_list(struct mes + max_addresses--; + if ((ret = parse_address(ctx)) == 0) + break; +- if (*ctx->parser.data != ',') { ++ if (ctx->parser.data >= ctx->parser.end || ++ *ctx->parser.data != ',') { + ret = -1; + break; + } +Index: dovecot-2.2.27/src/lib-mail/message-date.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-date.c 2018-02-26 12:46:05.152669582 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-date.c 2018-02-26 12:46:05.144669572 -0500 +@@ -103,7 +103,7 @@ static int next_token(struct message_dat + int ret; + + str_truncate(ctx->str, 0); +- ret = ctx->parser.data == ctx->parser.end ? 0 : ++ ret = ctx->parser.data >= ctx->parser.end ? 0 : + rfc822_parse_atom(&ctx->parser, ctx->str); + + *value = str_data(ctx->str); +@@ -205,7 +205,7 @@ message_date_parser_tokens(struct messag + tm.tm_min = (value[0]-'0') * 10 + (value[1]-'0'); + + /* [:ss] */ +- if (ctx->parser.data != ctx->parser.end && ++ if (ctx->parser.data < ctx->parser.end && + IS_TIME_SEP(*ctx->parser.data)) { + ctx->parser.data++; + rfc822_skip_lwsp(&ctx->parser); +Index: dovecot-2.2.27/src/lib-mail/rfc2231-parser.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/rfc2231-parser.c 2018-02-26 12:46:05.152669582 -0500 ++++ dovecot-2.2.27/src/lib-mail/rfc2231-parser.c 2018-02-26 12:46:05.148669577 -0500 +@@ -59,7 +59,7 @@ int rfc2231_parse(struct rfc822_parser_c + if (ret < 0) { + /* try to continue anyway.. */ + broken = TRUE; +- if (ctx->data == ctx->end) ++ if (ctx->data >= ctx->end) + break; + ctx->data++; + continue; +Index: dovecot-2.2.27/src/lib-mail/rfc822-parser.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/rfc822-parser.c 2018-02-26 12:46:05.152669582 -0500 ++++ dovecot-2.2.27/src/lib-mail/rfc822-parser.c 2018-02-26 12:46:05.148669577 -0500 +@@ -72,7 +72,7 @@ int rfc822_skip_comment(struct rfc822_pa + str_truncate(ctx->last_comment, 0); + + start = ++ctx->data; +- for (; ctx->data != ctx->end; ctx->data++) { ++ for (; ctx->data < ctx->end; ctx->data++) { + switch (*ctx->data) { + case '(': + level++; +@@ -84,7 +84,7 @@ int rfc822_skip_comment(struct rfc822_pa + ctx->data - start); + } + ctx->data++; +- return ctx->data != ctx->end; ++ return ctx->data < ctx->end ? 1 : 0; + } + break; + case '\\': +@@ -95,7 +95,7 @@ int rfc822_skip_comment(struct rfc822_pa + start = ctx->data + 1; + + ctx->data++; +- if (ctx->data == ctx->end) ++ if (ctx->data >= ctx->end) + return -1; + break; + } +@@ -107,7 +107,7 @@ int rfc822_skip_comment(struct rfc822_pa + + int rfc822_skip_lwsp(struct rfc822_parser_context *ctx) + { +- for (; ctx->data != ctx->end;) { ++ for (; ctx->data < ctx->end;) { + if (*ctx->data == ' ' || *ctx->data == '\t' || + *ctx->data == '\r' || *ctx->data == '\n') { + ctx->data++; +@@ -120,7 +120,7 @@ int rfc822_skip_lwsp(struct rfc822_parse + if (rfc822_skip_comment(ctx) < 0) + return -1; + } +- return ctx->data != ctx->end; ++ return ctx->data < ctx->end ? 1 : 0; + } + + int rfc822_parse_atom(struct rfc822_parser_context *ctx, string_t *str) +@@ -132,10 +132,10 @@ int rfc822_parse_atom(struct rfc822_pars + atext = + ; Any character except controls, SP, and specials. + */ +- if (ctx->data == ctx->end || !IS_ATEXT(*ctx->data)) ++ if (ctx->data >= ctx->end || !IS_ATEXT(*ctx->data)) + return -1; + +- for (start = ctx->data++; ctx->data != ctx->end; ctx->data++) { ++ for (start = ctx->data++; ctx->data < ctx->end; ctx->data++) { + if (IS_ATEXT(*ctx->data)) + continue; + +@@ -161,10 +161,10 @@ int rfc822_parse_dot_atom(struct rfc822_ + + For RFC-822 compatibility allow LWSP around '.' + */ +- if (ctx->data == ctx->end || !IS_ATEXT(*ctx->data)) ++ if (ctx->data >= ctx->end || !IS_ATEXT(*ctx->data)) + return -1; + +- for (start = ctx->data++; ctx->data != ctx->end; ) { ++ for (start = ctx->data++; ctx->data < ctx->end; ) { + if (IS_ATEXT(*ctx->data)) { + ctx->data++; + continue; +@@ -194,7 +194,7 @@ int rfc822_parse_mime_token(struct rfc82 + { + const unsigned char *start; + +- for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { ++ for (start = ctx->data; ctx->data < ctx->end; ctx->data++) { + if (IS_ATEXT_NON_TSPECIAL(*ctx->data) || *ctx->data == '.') + continue; + +@@ -215,7 +215,7 @@ int rfc822_parse_quoted_string(struct rf + i_assert(*ctx->data == '"'); + ctx->data++; + +- for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { ++ for (start = ctx->data; ctx->data < ctx->end; ctx->data++) { + switch (*ctx->data) { + case '"': + str_append_n(str, start, ctx->data - start); +@@ -231,7 +231,7 @@ int rfc822_parse_quoted_string(struct rf + break; + case '\\': + ctx->data++; +- if (ctx->data == ctx->end) ++ if (ctx->data >= ctx->end) + return -1; + + str_append_n(str, start, ctx->data - start - 1); +@@ -257,7 +257,7 @@ rfc822_parse_atom_or_dot(struct rfc822_p + The difference between this function and rfc822_parse_dot_atom() + is that this doesn't just silently skip over all the whitespace. + */ +- for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { ++ for (start = ctx->data; ctx->data < ctx->end; ctx->data++) { + if (IS_ATEXT(*ctx->data) || *ctx->data == '.') + continue; + +@@ -279,7 +279,7 @@ int rfc822_parse_phrase(struct rfc822_pa + obs-phrase = word *(word / "." / CFWS) + */ + +- if (ctx->data == ctx->end) ++ if (ctx->data >= ctx->end) + return 0; + if (*ctx->data == '.') + return -1; +@@ -317,10 +317,10 @@ rfc822_parse_domain_literal(struct rfc82 + i_assert(ctx->data < ctx->end); + i_assert(*ctx->data == '['); + +- for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { ++ for (start = ctx->data; ctx->data < ctx->end; ctx->data++) { + if (*ctx->data == '\\') { + ctx->data++; +- if (ctx->data == ctx->end) ++ if (ctx->data >= ctx->end) + break; + } else if (*ctx->data == ']') { + ctx->data++; +@@ -389,7 +389,7 @@ int rfc822_parse_content_param(struct rf + *key_r = NULL; + *value_r = NULL; + +- if (ctx->data == ctx->end) ++ if (ctx->data >= ctx->end) + return 0; + if (*ctx->data != ';') + return -1; +@@ -412,10 +412,10 @@ int rfc822_parse_content_param(struct rf + /* broken / no value */ + } else if (*ctx->data == '"') { + ret = rfc822_parse_quoted_string(ctx, tmp); +- } else if (ctx->data != ctx->end && *ctx->data == '=') { ++ } else if (ctx->data < ctx->end && *ctx->data == '=') { + /* workaround for broken input: + name==?utf-8?b?...?= */ +- while (ctx->data != ctx->end && *ctx->data != ';' && ++ while (ctx->data < ctx->end && *ctx->data != ';' && + *ctx->data != ' ' && *ctx->data != '\t' && + *ctx->data != '\r' && *ctx->data != '\n') { + str_append_c(tmp, *ctx->data); +Index: dovecot-2.2.27/src/lib-imap/imap-bodystructure.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-imap/imap-bodystructure.c 2016-12-03 12:13:21.000000000 -0500 ++++ dovecot-2.2.27/src/lib-imap/imap-bodystructure.c 2018-02-26 13:12:39.622160356 -0500 +@@ -158,7 +158,7 @@ static void parse_content_language(const + while (rfc822_parse_atom(&parser, str) >= 0) { + str_append(str, "\" \""); + +- if (parser.data == parser.end || *parser.data != ',') ++ if (parser.data >= parser.end || *parser.data != ',') + break; + parser.data++; + rfc822_skip_lwsp(&parser); diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-14461/0005-lib-mail-Add-rfc822_parser_deinit.patch dovecot-2.2.27/debian/patches/CVE-2017-14461/0005-lib-mail-Add-rfc822_parser_deinit.patch --- dovecot-2.2.27/debian/patches/CVE-2017-14461/0005-lib-mail-Add-rfc822_parser_deinit.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-14461/0005-lib-mail-Add-rfc822_parser_deinit.patch 2018-02-26 17:31:05.000000000 +0000 @@ -0,0 +1,33 @@ +From f5cd17a27f0b666567747f8c921ebe1026970f11 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Fri, 22 Dec 2017 18:56:53 +0200 +Subject: [PATCH 5/7] lib-mail: Add rfc822_parser_deinit() + +It's not a strict requirement to call this, but it assert-crashes if the +state isn't valid. +--- + src/lib-mail/rfc822-parser.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/lib-mail/rfc822-parser.h b/src/lib-mail/rfc822-parser.h +index 87e9aa2..466a68a 100644 +--- a/src/lib-mail/rfc822-parser.h ++++ b/src/lib-mail/rfc822-parser.h +@@ -16,6 +16,14 @@ extern unsigned char rfc822_atext_chars[256]; + void rfc822_parser_init(struct rfc822_parser_context *ctx, + const unsigned char *data, size_t size, + string_t *last_comment) ATTR_NULL(4); ++static inline void rfc822_parser_deinit(struct rfc822_parser_context *ctx) ++{ ++ /* make sure the parsing didn't trigger a bug that caused reading ++ past the end pointer. */ ++ i_assert(ctx->data <= ctx->end); ++ /* make sure the parser is no longer accessed */ ++ ctx->data = ctx->end = NULL; ++} + + /* The functions below return 1 = more data available, 0 = no more data + available (but a value might have been returned now), -1 = invalid input. +-- +2.1.4 + diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-14461/0006-lib-mail-Refactor-code-to-make-the-next-commit-small.patch dovecot-2.2.27/debian/patches/CVE-2017-14461/0006-lib-mail-Refactor-code-to-make-the-next-commit-small.patch --- dovecot-2.2.27/debian/patches/CVE-2017-14461/0006-lib-mail-Refactor-code-to-make-the-next-commit-small.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-14461/0006-lib-mail-Refactor-code-to-make-the-next-commit-small.patch 2018-02-26 18:13:03.000000000 +0000 @@ -0,0 +1,91 @@ +From 18a7a161c8dae6f630770a3cbab7374a0c3dd732 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Tue, 9 Jan 2018 11:33:59 -0500 +Subject: [PATCH 6/7] lib-mail: Refactor code to make the next commit smaller + +--- + src/lib-mail/message-address.c | 4 ++-- + src/lib-mail/message-id.c | 30 +++++++++++++----------------- + src/lib-mail/message-parser.c | 5 ++--- + 3 files changed, 17 insertions(+), 22 deletions(-) + +Index: dovecot-2.2.27/src/lib-mail/message-address.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-address.c 2018-02-26 13:13:00.170180559 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-address.c 2018-02-26 13:13:00.170180559 -0500 +@@ -322,9 +322,9 @@ message_address_parse_real(pool_t pool, + + if (rfc822_skip_lwsp(&ctx.parser) <= 0) { + /* no addresses */ +- return NULL; ++ } else { ++ (void)parse_address_list(&ctx, max_addresses); + } +- (void)parse_address_list(&ctx, max_addresses); + return ctx.first_addr; + } + +Index: dovecot-2.2.27/src/lib-mail/message-id.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-id.c 2018-02-26 13:13:00.170180559 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-id.c 2018-02-26 13:13:00.170180559 -0500 +@@ -9,6 +9,7 @@ static bool get_untokenized_msgid(const + { + struct rfc822_parser_context parser; + int ret; ++ bool success = FALSE; + + rfc822_parser_init(&parser, (const unsigned char *)*msgid_p, + strlen(*msgid_p), NULL); +@@ -27,23 +28,18 @@ static bool get_untokenized_msgid(const + ret = rfc822_parse_quoted_string(&parser, msgid); + else + ret = rfc822_parse_dot_atom(&parser, msgid); +- if (ret <= 0) +- return FALSE; +- +- if (*parser.data != '@') +- return FALSE; +- str_append_c(msgid, '@'); +- parser.data++; +- rfc822_skip_lwsp(&parser); +- +- if (rfc822_parse_dot_atom(&parser, msgid) <= 0) +- return FALSE; +- +- if (*parser.data != '>') +- return FALSE; +- +- *msgid_p = (const char *)parser.data + 1; +- return TRUE; ++ if (ret > 0 && *parser.data == '@') { ++ str_append_c(msgid, '@'); ++ parser.data++; ++ rfc822_skip_lwsp(&parser); ++ ++ if (rfc822_parse_dot_atom(&parser, msgid) > 0 && ++ *parser.data == '>') { ++ *msgid_p = (const char *)parser.data + 1; ++ success = TRUE; ++ } ++ } ++ return success; + } + + static void strip_lwsp(char *str) +Index: dovecot-2.2.27/src/lib-mail/message-parser.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-parser.c 2018-02-26 13:13:00.170180559 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-parser.c 2018-02-26 13:13:00.170180559 -0500 +@@ -499,9 +499,8 @@ static void parse_content_type(struct me + ctx->part->flags |= MESSAGE_PART_FLAG_MULTIPART_DIGEST; + } + +- if (ret < 0) +- return; +- if ((ctx->part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 || ++ if (ret < 0 || ++ (ctx->part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 || + ctx->last_boundary != NULL) + return; + diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-14461/0007-global-Call-rfc822_parser_deinit-wherever-possible.patch dovecot-2.2.27/debian/patches/CVE-2017-14461/0007-global-Call-rfc822_parser_deinit-wherever-possible.patch --- dovecot-2.2.27/debian/patches/CVE-2017-14461/0007-global-Call-rfc822_parser_deinit-wherever-possible.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-14461/0007-global-Call-rfc822_parser_deinit-wherever-possible.patch 2018-02-26 18:19:19.000000000 +0000 @@ -0,0 +1,246 @@ +Backport of: + +From 0ed696987e5e5d44e971da2a10f6275b276ece34 Mon Sep 17 00:00:00 2001 +From: Timo Sirainen +Date: Fri, 22 Dec 2017 18:58:11 +0200 +Subject: [PATCH 7/7] global: Call rfc822_parser_deinit() wherever possible + +--- + src/lib-mail/istream-attachment-extractor.c | 1 + + src/lib-mail/message-address.c | 1 + + src/lib-mail/message-date.c | 1 + + src/lib-mail/message-decoder.c | 6 +++++- + src/lib-mail/message-id.c | 1 + + src/lib-mail/message-parser.c | 5 ++++- + src/lib-mail/message-part-data.c | 8 +++++++- + src/lib-mail/message-search.c | 1 + + src/lib-mail/test-rfc2231-parser.c | 1 + + src/lib-mail/test-rfc822-parser.c | 2 ++ + src/plugins/fts/fts-build-mail.c | 1 + + src/plugins/fts/fts-parser-script.c | 5 ++++- + 12 files changed, 29 insertions(+), 4 deletions(-) + +Index: dovecot-2.2.27/src/lib-mail/istream-attachment-extractor.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/istream-attachment-extractor.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/istream-attachment-extractor.c 2018-02-26 13:13:15.266195543 -0500 +@@ -88,6 +88,7 @@ static void parse_content_type(struct at + (void)rfc822_parse_content_type(&parser, content_type); + astream->part.content_type = i_strdup(str_c(content_type)); + } T_END; ++ rfc822_parser_deinit(&parser); + } + + static void +Index: dovecot-2.2.27/src/lib-mail/message-address.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-address.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-address.c 2018-02-26 13:13:15.266195543 -0500 +@@ -325,6 +325,7 @@ message_address_parse_real(pool_t pool, + } else { + (void)parse_address_list(&ctx, max_addresses); + } ++ rfc822_parser_deinit(&ctx.parser); + return ctx.first_addr; + } + +Index: dovecot-2.2.27/src/lib-mail/message-date.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-date.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-date.c 2018-02-26 13:13:15.266195543 -0500 +@@ -252,6 +252,7 @@ bool message_date_parse(const unsigned c + ctx.str = t_str_new(128); + success = message_date_parser_tokens(&ctx, timestamp_r, + timezone_offset_r); ++ rfc822_parser_deinit(&ctx.parser); + } T_END; + + return success; +Index: dovecot-2.2.27/src/lib-mail/message-decoder.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-decoder.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-decoder.c 2018-02-26 13:13:15.266195543 -0500 +@@ -117,6 +117,7 @@ enum message_cte message_decoder_parse_c + message_cte = MESSAGE_CTE_QP; + break; + } ++ rfc822_parser_deinit(&parser); + return message_cte; + } + +@@ -137,8 +138,10 @@ parse_content_type(struct message_decode + str = t_str_new(64); + ret = rfc822_parse_content_type(&parser, str); + ctx->content_type = i_strdup(str_c(str)); +- if (ret < 0) ++ if (ret < 0) { ++ rfc822_parser_deinit(&parser); + return; ++ } + + rfc2231_parse(&parser, &results); + for (; *results != NULL; results += 2) { +@@ -147,6 +150,7 @@ parse_content_type(struct message_decode + break; + } + } ++ rfc822_parser_deinit(&parser); + } + + static bool message_decode_header(struct message_decoder_context *ctx, +Index: dovecot-2.2.27/src/lib-mail/message-id.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-id.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-id.c 2018-02-26 13:13:15.266195543 -0500 +@@ -39,6 +39,7 @@ static bool get_untokenized_msgid(const + success = TRUE; + } + } ++ rfc822_parser_deinit(&parser); + return success; + } + +Index: dovecot-2.2.27/src/lib-mail/message-parser.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-parser.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-parser.c 2018-02-26 13:13:15.266195543 -0500 +@@ -501,8 +501,10 @@ static void parse_content_type(struct me + + if (ret < 0 || + (ctx->part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 || +- ctx->last_boundary != NULL) ++ ctx->last_boundary != NULL) { ++ rfc822_parser_deinit(&parser); + return; ++ } + + rfc2231_parse(&parser, &results); + for (; *results != NULL; results += 2) { +@@ -512,6 +514,7 @@ static void parse_content_type(struct me + break; + } + } ++ rfc822_parser_deinit(&parser); + } + + static bool block_is_at_eoh(const struct message_block *block) +Index: dovecot-2.2.27/src/lib-mail/message-search.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/message-search.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/message-search.c 2018-02-26 13:13:15.266195543 -0500 +@@ -61,6 +61,7 @@ static void parse_content_type(struct me + ctx->content_type_text = + strncasecmp(str_c(content_type), "text/", 5) == 0 || + strncasecmp(str_c(content_type), "message/", 8) == 0; ++ rfc822_parser_deinit(&parser); + } + + static void handle_header(struct message_search_context *ctx, +Index: dovecot-2.2.27/src/lib-mail/test-rfc2231-parser.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/test-rfc2231-parser.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/test-rfc2231-parser.c 2018-02-26 13:13:15.266195543 -0500 +@@ -36,6 +36,7 @@ static void test_rfc2231_parser(void) + test_assert(rfc2231_parse(&parser, &result) == 0); + for (i = 0; output[i] != NULL && result[i] != NULL; i++) + test_assert(strcmp(output[i], result[i]) == 0); ++ rfc822_parser_deinit(&parser); + test_assert(output[i] == NULL && result[i] == NULL); + test_end(); + } +Index: dovecot-2.2.27/src/lib-mail/test-rfc822-parser.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-mail/test-rfc822-parser.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/lib-mail/test-rfc822-parser.c 2018-02-26 13:13:15.266195543 -0500 +@@ -31,6 +31,7 @@ static void test_rfc822_parse_quoted_str + test_assert_idx(rfc822_parse_quoted_string(&parser, str) == tests[i].ret, i); + test_assert_idx(tests[i].ret < 0 || + strcmp(tests[i].output, str_c(str)) == 0, i); ++ rfc822_parser_deinit(&parser); + str_truncate(str, 0); + } + test_end(); +@@ -60,6 +61,7 @@ static void test_rfc822_parse_content_pa + test_assert_idx(strcmp(output[i].value, value) == 0, i); + i++; + } ++ rfc822_parser_deinit(&parser); + test_assert(ret == 0); + test_assert(i == N_ELEMENTS(output)); + test_end(); +Index: dovecot-2.2.27/src/plugins/fts/fts-build-mail.c +=================================================================== +--- dovecot-2.2.27.orig/src/plugins/fts/fts-build-mail.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/plugins/fts/fts-build-mail.c 2018-02-26 13:13:15.266195543 -0500 +@@ -56,6 +56,7 @@ static void fts_build_parse_content_type + (void)rfc822_parse_content_type(&parser, content_type); + ctx->content_type = str_lcase(i_strdup(str_c(content_type))); + } T_END; ++ rfc822_parser_deinit(&parser); + } + + static void +Index: dovecot-2.2.27/src/plugins/fts/fts-parser-script.c +=================================================================== +--- dovecot-2.2.27.orig/src/plugins/fts/fts-parser-script.c 2018-02-26 13:13:15.266195543 -0500 ++++ dovecot-2.2.27/src/plugins/fts/fts-parser-script.c 2018-02-26 13:13:15.266195543 -0500 +@@ -173,8 +173,10 @@ static void parse_content_disposition(co + + /* type; param; param; .. */ + str = t_str_new(32); +- if (rfc822_parse_mime_token(&parser, str) < 0) ++ if (rfc822_parse_mime_token(&parser, str) < 0) { ++ rfc822_parser_deinit(&parser); + return; ++ } + + rfc2231_parse(&parser, &results); + filename2 = NULL; +@@ -191,6 +193,7 @@ static void parse_content_disposition(co + much about the filename actually, just about its extension */ + *filename_r = filename2; + } ++ rfc822_parser_deinit(&parser); + } + + static struct fts_parser * +Index: dovecot-2.2.27/src/lib-imap/imap-bodystructure.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-imap/imap-bodystructure.c 2018-02-26 13:12:39.622160356 -0500 ++++ dovecot-2.2.27/src/lib-imap/imap-bodystructure.c 2018-02-26 13:17:05.594436695 -0500 +@@ -106,6 +106,7 @@ static void parse_content_transfer_encod + data->content_transfer_encoding = + imap_get_string(data->pool, str_c(str)); + } ++ rfc822_parser_deinit(&parser); + } + + static void parse_content_disposition(struct message_part_body_data *data, +@@ -119,8 +120,10 @@ static void parse_content_disposition(st + rfc822_skip_lwsp(&parser); + + str = t_str_new(256); +- if (rfc822_parse_mime_token(&parser, str) < 0) ++ if (rfc822_parse_mime_token(&parser, str) < 0) { ++ rfc822_parser_deinit(&parser); + return; ++ } + data->content_disposition = imap_get_string(data->pool, str_c(str)); + + /* parse parameters and save them */ +@@ -136,6 +139,7 @@ static void parse_content_disposition(st + data->content_disposition_params = + p_strdup(data->pool, str_c(str) + 1); + } ++ rfc822_parser_deinit(&parser); + } + + static void parse_content_language(const unsigned char *value, size_t value_len, +@@ -168,6 +172,7 @@ static void parse_content_language(const + str_truncate(str, str_len(str) - 2); + data->content_language = p_strdup(data->pool, str_c(str)); + } ++ rfc822_parser_deinit(&parser); + } + + static void parse_content_header(struct message_part_body_data *d, diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-15130/0001-lib-dns-Move-before-lib-master.patch dovecot-2.2.27/debian/patches/CVE-2017-15130/0001-lib-dns-Move-before-lib-master.patch --- dovecot-2.2.27/debian/patches/CVE-2017-15130/0001-lib-dns-Move-before-lib-master.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-15130/0001-lib-dns-Move-before-lib-master.patch 2018-02-26 17:32:31.000000000 +0000 @@ -0,0 +1,29 @@ +From 22311315b9f780211329c1522eb5aaa4faaa9391 Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Mon, 19 Feb 2018 14:19:08 +0200 +Subject: [PATCH 1/6] lib-dns: Move before lib-master + +--- + src/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/Makefile.am b/src/Makefile.am +index e1e40e1..c1f87ee 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -7,11 +7,11 @@ LIBDOVECOT_SUBDIRS = \ + lib \ + lib-settings \ + lib-auth \ ++ lib-dns \ + lib-master \ + lib-charset \ + lib-ssl-iostream \ + lib-dcrypt \ +- lib-dns \ + lib-dict \ + lib-sasl \ + lib-stats \ +-- +2.1.4 + diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-15130/0002-config-Add-config_filter_get_all.patch dovecot-2.2.27/debian/patches/CVE-2017-15130/0002-config-Add-config_filter_get_all.patch --- dovecot-2.2.27/debian/patches/CVE-2017-15130/0002-config-Add-config_filter_get_all.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-15130/0002-config-Add-config_filter_get_all.patch 2018-02-26 18:17:47.000000000 +0000 @@ -0,0 +1,51 @@ +From f3504763c27c2661716c0d1dbd3e0fc662107a21 Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Thu, 30 Nov 2017 15:46:40 +0200 +Subject: [PATCH 2/6] config: Add config_filter_get_all + +Returns all filters +--- + src/config/config-filter.c | 15 +++++++++++++++ + src/config/config-filter.h | 3 +++ + 2 files changed, 18 insertions(+) + +Index: dovecot-2.2.27/src/config/config-filter.c +=================================================================== +--- dovecot-2.2.27.orig/src/config/config-filter.c 2018-02-26 13:17:45.074479994 -0500 ++++ dovecot-2.2.27/src/config/config-filter.c 2018-02-26 13:17:45.070479989 -0500 +@@ -242,6 +242,21 @@ config_filter_find_all(struct config_fil + } + + struct config_filter_parser *const * ++config_filter_get_all(struct config_filter_context *ctx) ++{ ++ ARRAY_TYPE(config_filter_parsers) filters; ++ unsigned int i; ++ ++ t_array_init(&filters, 8); ++ for (i = 0; ctx->parsers[i] != NULL; i++) { ++ array_append(&filters, &ctx->parsers[i], 1); ++ } ++ array_sort(&filters, config_filter_parser_cmp_rev); ++ array_append_zero(&filters); ++ return array_idx(&filters, 0); ++} ++ ++struct config_filter_parser *const * + config_filter_find_subset(struct config_filter_context *ctx, + const struct config_filter *filter) + { +Index: dovecot-2.2.27/src/config/config-filter.h +=================================================================== +--- dovecot-2.2.27.orig/src/config/config-filter.h 2018-02-26 13:17:45.074479994 -0500 ++++ dovecot-2.2.27/src/config/config-filter.h 2018-02-26 13:17:45.070479989 -0500 +@@ -45,6 +45,9 @@ struct config_filter_parser *const * + config_filter_find_subset(struct config_filter_context *ctx, + const struct config_filter *filter); + ++struct config_filter_parser *const * ++config_filter_get_all(struct config_filter_context *ctx); ++ + /* Returns TRUE if filter matches mask. */ + bool config_filter_match(const struct config_filter *mask, + const struct config_filter *filter); diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-15130/0003-config-Add-command-to-request-all-filters.patch dovecot-2.2.27/debian/patches/CVE-2017-15130/0003-config-Add-command-to-request-all-filters.patch --- dovecot-2.2.27/debian/patches/CVE-2017-15130/0003-config-Add-command-to-request-all-filters.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-15130/0003-config-Add-command-to-request-all-filters.patch 2018-02-26 18:17:50.000000000 +0000 @@ -0,0 +1,61 @@ +From 02da33a59fddd51cc3b8d95989de95574b7332f1 Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Thu, 30 Nov 2017 15:46:52 +0200 +Subject: [PATCH 3/6] config: Add command to request all filters + +--- + src/config/config-connection.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +Index: dovecot-2.2.27/src/config/config-connection.c +=================================================================== +--- dovecot-2.2.27.orig/src/config/config-connection.c 2018-02-26 13:17:48.854484164 -0500 ++++ dovecot-2.2.27/src/config/config-connection.c 2018-02-26 13:17:48.850484161 -0500 +@@ -149,6 +149,36 @@ static int config_connection_request(str + return 0; + } + ++static int config_filters_request(struct config_connection *conn) ++{ ++ struct config_filter_parser *const *filters = config_filter_get_all(config_filter); ++ o_stream_cork(conn->output); ++ while(*filters != NULL) { ++ const struct config_filter *filter = &(*filters)->filter; ++ o_stream_nsend_str(conn->output, "FILTER"); ++ if (filter->service != NULL) ++ o_stream_nsend_str(conn->output, t_strdup_printf("\tservice=%s", ++ filter->service)); ++ if (filter->local_name != NULL) ++ o_stream_nsend_str(conn->output, t_strdup_printf("\tlocal-name=%s", ++ filter->local_name)); ++ if (filter->local_bits > 0) ++ o_stream_nsend_str(conn->output, t_strdup_printf("\tlocal-net=%s/%u", ++ net_ip2addr(&filter->local_net), ++ filter->local_bits)); ++ if (filter->remote_bits > 0) ++ o_stream_nsend_str(conn->output, t_strdup_printf("\tremote-net=%s/%u", ++ net_ip2addr(&filter->remote_net), ++ filter->remote_bits)); ++ o_stream_nsend_str(conn->output, "\n"); ++ filters++; ++ } ++ o_stream_nsend_str(conn->output, "\n"); ++ o_stream_uncork(conn->output); ++ return 0; ++} ++ ++ + static void config_connection_input(struct config_connection *conn) + { + const char *const *args, *line; +@@ -185,6 +215,10 @@ static void config_connection_input(stru + if (config_connection_request(conn, args + 1) < 0) + break; + } ++ if (strcmp(args[0], "FILTERS") == 0) { ++ if (config_filters_request(conn) < 0) ++ break; ++ } + } + } + diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-15130/0004-lib-master-Support-validating-config-filters-against.patch dovecot-2.2.27/debian/patches/CVE-2017-15130/0004-lib-master-Support-validating-config-filters-against.patch --- dovecot-2.2.27/debian/patches/CVE-2017-15130/0004-lib-master-Support-validating-config-filters-against.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-15130/0004-lib-master-Support-validating-config-filters-against.patch 2018-02-26 18:19:51.000000000 +0000 @@ -0,0 +1,297 @@ +Backport of: + +From 390592e6af07e02064ebdbb1bbcf06528887370f Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Thu, 30 Nov 2017 15:47:25 +0200 +Subject: [PATCH 4/6] lib-master: Support validating config filters against + requests + +Validation will sanitize the input request and drop any fields +that have no filter in config. E.g. if you have a local block +with name, and nothing else, then lip/rip will be dropped +from the request. +--- + src/lib-master/Makefile.am | 2 + + src/lib-master/master-service-settings-cache.c | 90 ++++++++++++++++++++++ + src/lib-master/master-service-settings-cache.h | 2 +- + src/lib-master/master-service-settings.c | 60 +++++++++++++++ + src/lib-master/master-service-settings.h | 3 + + .../test-master-service-settings-cache.c | 8 ++ + 6 files changed, 164 insertions(+), 1 deletion(-) + +Index: dovecot-2.2.27/src/lib-master/Makefile.am +=================================================================== +--- dovecot-2.2.27.orig/src/lib-master/Makefile.am 2018-02-26 14:23:23.953548649 -0500 ++++ dovecot-2.2.27/src/lib-master/Makefile.am 2018-02-26 14:23:23.953548649 -0500 +@@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libmaster.la + + AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ ++ -I$(top_srcdir)/src/lib-dns \ + -I$(top_srcdir)/src/lib-test \ + -I$(top_srcdir)/src/lib-settings \ + -I$(top_srcdir)/src/lib-ssl-iostream \ +@@ -58,6 +59,7 @@ noinst_PROGRAMS = $(test_programs) + + test_libs = \ + ../lib-test/libtest.la \ ++ ../lib-dns/libdns.la \ + ../lib/liblib.la + + test_deps = $(noinst_LTLIBRARIES) $(test_libs) +Index: dovecot-2.2.27/src/lib-master/master-service-settings-cache.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-master/master-service-settings-cache.c 2018-02-26 14:23:23.953548649 -0500 ++++ dovecot-2.2.27/src/lib-master/master-service-settings-cache.c 2018-02-26 14:23:23.953548649 -0500 +@@ -1,9 +1,11 @@ + /* Copyright (c) 2010-2016 Dovecot authors, see the included COPYING file */ + + #include "lib.h" ++#include "wildcard-match.h" + #include "hash.h" + #include "llist.h" + #include "settings-parser.h" ++#include "dns-util.h" + #include "master-service-private.h" + #include "master-service-settings.h" + #include "master-service-settings-cache.h" +@@ -12,6 +14,14 @@ + #define CACHE_INITIAL_ENTRY_POOL_SIZE (1024*16) + #define CACHE_ADD_ENTRY_POOL_SIZE 1024 + ++struct config_filter { ++ struct config_filter *prev, *next; ++ ++ const char *local_name; ++ struct ip_addr local_ip, remote_ip; ++ unsigned int local_bits, remote_bits; ++}; ++ + struct settings_entry { + struct settings_entry *prev, *next; + +@@ -41,6 +51,8 @@ struct master_service_settings_cache { + HASH_TABLE(char *, struct settings_entry *) local_name_hash; + HASH_TABLE(struct ip_addr *, struct settings_entry *) local_ip_hash; + ++ struct config_filter *filters; ++ + /* Initial size for new settings entry pools */ + size_t approx_entry_pool_size; + /* number of bytes malloced by cached settings entries +@@ -70,6 +82,78 @@ master_service_settings_cache_init(struc + return cache; + } + ++int master_service_settings_cache_init_filter(struct master_service_settings_cache *cache) ++{ ++ const char *const *filters; ++ const char *error; ++ ++ if (cache->filters != NULL) ++ return 0; ++ if (master_service_settings_get_filters(cache->service, &filters, &error) < 0) { ++ i_error("master-service: cannot get filters: %s", error); ++ return -1; ++ } ++ ++ /* parse filters */ ++ while(*filters != NULL) { ++ const char *const *keys = t_strsplit_spaces(*filters, " "); ++ struct config_filter *filter = ++ p_new(cache->pool, struct config_filter, 1); ++ while(*keys != NULL) { ++ if (strncmp(*keys, "local-net=", 10) == 0) { ++ (void)net_parse_range((*keys)+10, ++ &filter->local_ip, &filter->local_bits); ++ } else if (strncmp(*keys, "remote-net=", 11) == 0) { ++ (void)net_parse_range((*keys)+11, ++ &filter->remote_ip, &filter->remote_bits); ++ } else if (strncmp(*keys, "local-name=", 11) == 0) { ++ filter->local_name = p_strdup(cache->pool, (*keys)+11); ++ } ++ keys++; ++ } ++ DLLIST_PREPEND(&cache->filters, filter); ++ filters++; ++ } ++ return 0; ++} ++ ++/* Remove any elements which there is no filter for */ ++static void ++master_service_settings_cache_fix_input(struct master_service_settings_cache *cache, ++ const struct master_service_settings_input *input, ++ struct master_service_settings_input *new_input) ++{ ++ bool found_lip, found_rip, found_local_name; ++ ++ found_lip = found_rip = found_local_name = FALSE; ++ ++ struct config_filter *filter = cache->filters; ++ while(filter != NULL) { ++ if (filter->local_bits > 0 && ++ net_is_in_network(&input->local_ip, &filter->local_ip, ++ filter->local_bits)) ++ found_lip = TRUE; ++ if (filter->remote_bits > 0 && ++ net_is_in_network(&input->remote_ip, &filter->remote_ip, ++ filter->remote_bits)) ++ found_rip = TRUE; ++ if (input->local_name != NULL && filter->local_name != NULL && ++ dns_match_wildcard(input->local_name, filter->local_name)) ++ found_local_name = TRUE; ++ filter = filter->next; ++ }; ++ ++ *new_input = *input; ++ ++ if (!found_lip) ++ memset(&new_input->local_ip, 0, sizeof(new_input->local_ip)); ++ if (!found_rip) ++ memset(&new_input->remote_ip, 0, sizeof(new_input->remote_ip)); ++ if (!found_local_name) ++ new_input->local_name = NULL; ++} ++ ++ + void master_service_settings_cache_deinit(struct master_service_settings_cache **_cache) + { + struct master_service_settings_cache *cache = *_cache; +@@ -273,6 +357,12 @@ int master_service_settings_cache_read(s + return 0; + + new_input = *input; ++ if (cache->filters != NULL) { ++ master_service_settings_cache_fix_input(cache, input, &new_input); ++ if (cache_find(cache, &new_input, parser_r)) ++ return 0; ++ } ++ + if (dyn_parsers != NULL) { + settings_parser_dyn_update(cache->pool, &new_input.roots, + dyn_parsers); +Index: dovecot-2.2.27/src/lib-master/master-service-settings-cache.h +=================================================================== +--- dovecot-2.2.27.orig/src/lib-master/master-service-settings-cache.h 2018-02-26 14:23:23.953548649 -0500 ++++ dovecot-2.2.27/src/lib-master/master-service-settings-cache.h 2018-02-26 14:23:23.953548649 -0500 +@@ -6,7 +6,7 @@ master_service_settings_cache_init(struc + const char *module, + const char *service_name); + void master_service_settings_cache_deinit(struct master_service_settings_cache **cache); +- ++int master_service_settings_cache_init_filter(struct master_service_settings_cache *cache); + int master_service_settings_cache_read(struct master_service_settings_cache *cache, + const struct master_service_settings_input *input, + const struct dynamic_settings_parser *dyn_parsers, +Index: dovecot-2.2.27/src/lib-master/master-service-settings.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-master/master-service-settings.c 2018-02-26 14:23:23.953548649 -0500 ++++ dovecot-2.2.27/src/lib-master/master-service-settings.c 2018-02-26 14:23:23.953548649 -0500 +@@ -288,6 +288,18 @@ config_send_request(struct master_servic + } + + static int ++config_send_filters_request(int fd, const char *path, const char **error_r) ++{ ++ int ret; ++ ret = write_full(fd, CONFIG_HANDSHAKE"FILTERS\n", strlen(CONFIG_HANDSHAKE"FILTERS\n")); ++ if (ret < 0) { ++ *error_r = t_strdup_printf("write_full(%s) failed: %m", path); ++ return -1; ++ } ++ return 0; ++} ++ ++static int + master_service_apply_config_overrides(struct master_service *service, + struct setting_parser_context *parser, + const char **error_r) +@@ -383,6 +395,54 @@ void master_service_config_socket_try_op + service->config_fd = fd; + } + ++int master_service_settings_get_filters(struct master_service *service, ++ const char *const **filters, ++ const char **error_r) ++{ ++ struct master_service_settings_input input; ++ int fd; ++ bool retry = TRUE; ++ const char *path = NULL; ++ ARRAY_TYPE(const_string) filters_tmp; ++ t_array_init(&filters_tmp, 8); ++ memset(&input, 0, sizeof(input)); ++ ++ if (getenv("DOVECONF_ENV") == NULL && ++ (service->flags & MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0) { ++ retry = service->config_fd != -1; ++ for (;;) { ++ fd = master_service_open_config(service, &input, &path, error_r); ++ if (fd == -1) { ++ return -1; ++ } ++ if (config_send_filters_request(fd, path, error_r) == 0) ++ break; ++ ++ i_close_fd(&fd); ++ if (!retry) ++ return -1; ++ retry = FALSE; ++ } ++ service->config_fd = fd; ++ struct istream *is = i_stream_create_fd(fd, (size_t)-1, FALSE); ++ const char *line; ++ /* try read response */ ++ while((line = i_stream_read_next_line(is)) != NULL) { ++ if (*line == '\0') ++ break; ++ if (strncmp(line, "FILTER\t", 7) == 0) { ++ line = t_strdup(line+7); ++ array_append(&filters_tmp, &line, 1); ++ } ++ } ++ i_stream_unref(&is); ++ } ++ ++ array_append_zero(&filters_tmp); ++ *filters = array_idx(&filters_tmp, 0); ++ return 0; ++} ++ + int master_service_settings_read(struct master_service *service, + const struct master_service_settings_input *input, + struct master_service_settings_output *output_r, +Index: dovecot-2.2.27/src/lib-master/master-service-settings.h +=================================================================== +--- dovecot-2.2.27.orig/src/lib-master/master-service-settings.h 2018-02-26 14:23:23.953548649 -0500 ++++ dovecot-2.2.27/src/lib-master/master-service-settings.h 2018-02-26 14:23:23.953548649 -0500 +@@ -66,6 +66,9 @@ extern const struct setting_parser_info + /* Try to open the config socket if it's going to be needed later by + master_service_settings_read*() */ + void master_service_config_socket_try_open(struct master_service *service); ++int master_service_settings_get_filters(struct master_service *service, ++ const char *const **filters, ++ const char **error_r); + int master_service_settings_read(struct master_service *service, + const struct master_service_settings_input *input, + struct master_service_settings_output *output_r, +Index: dovecot-2.2.27/src/lib-master/test-master-service-settings-cache.c +=================================================================== +--- dovecot-2.2.27.orig/src/lib-master/test-master-service-settings-cache.c 2018-02-26 14:23:23.953548649 -0500 ++++ dovecot-2.2.27/src/lib-master/test-master-service-settings-cache.c 2018-02-26 14:23:23.953548649 -0500 +@@ -53,6 +53,14 @@ int master_service_settings_read(struct + return 0; + } + ++int master_service_settings_get_filters(struct master_service *service ATTR_UNUSED, ++ const char *const **filters ATTR_UNUSED, ++ const char **error_r ATTR_UNUSED) ++{ ++ return -1; ++} ++ ++ + const struct master_service_settings * + master_service_settings_get(struct master_service *service ATTR_UNUSED) + { diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-15130/0005-login-common-Enable-config-filtering-by-local-name.patch dovecot-2.2.27/debian/patches/CVE-2017-15130/0005-login-common-Enable-config-filtering-by-local-name.patch --- dovecot-2.2.27/debian/patches/CVE-2017-15130/0005-login-common-Enable-config-filtering-by-local-name.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-15130/0005-login-common-Enable-config-filtering-by-local-name.patch 2018-02-26 17:33:27.000000000 +0000 @@ -0,0 +1,29 @@ +From bc27538d084e01a7a1aca3330e27aebfc0e311eb Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Thu, 30 Nov 2017 20:52:11 +0200 +Subject: [PATCH 5/6] login-common: Enable config filtering by local name + +Prevents servername misuse. +--- + src/login-common/login-settings.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +Index: dovecot-2.2.33.2/src/login-common/login-settings.c +=================================================================== +--- dovecot-2.2.33.2.orig/src/login-common/login-settings.c 2018-02-26 12:33:24.563777040 -0500 ++++ dovecot-2.2.33.2/src/login-common/login-settings.c 2018-02-26 12:33:24.563777040 -0500 +@@ -183,6 +183,14 @@ login_settings_read(pool_t pool, + set_cache = master_service_settings_cache_init(master_service, + input.module, + input.service); ++ /* lookup filters ++ ++ this is only enabled if service_count > 1 because otherwise ++ login process will process only one request and this is only ++ useful when more than one request is processed. ++ */ ++ if (master_service_get_service_count(master_service) > 1) ++ master_service_settings_cache_init_filter(set_cache); + } + + if (master_service_settings_cache_read(set_cache, &input, NULL, diff -Nru dovecot-2.2.27/debian/patches/CVE-2017-15130/0006-lib-master-Fix-dns_match_wildcard-result-value-check.patch dovecot-2.2.27/debian/patches/CVE-2017-15130/0006-lib-master-Fix-dns_match_wildcard-result-value-check.patch --- dovecot-2.2.27/debian/patches/CVE-2017-15130/0006-lib-master-Fix-dns_match_wildcard-result-value-check.patch 1970-01-01 00:00:00.000000000 +0000 +++ dovecot-2.2.27/debian/patches/CVE-2017-15130/0006-lib-master-Fix-dns_match_wildcard-result-value-check.patch 2018-02-26 17:33:31.000000000 +0000 @@ -0,0 +1,20 @@ +From 00016646cc32a3fa1cf54c22ed7388ed06bbc0f1 Mon Sep 17 00:00:00 2001 +From: Aki Tuomi +Date: Mon, 26 Feb 2018 12:53:19 +0200 +Subject: [PATCH 6/6] lib-master: Fix dns_match_wildcard result value check + +It returns 0, not TRUE. + +diff --git a/src/lib-master/master-service-settings-cache.c b/src/lib-master/master-service-settings-cache.c +index 11e9204..471c6a1 100644 +--- a/src/lib-master/master-service-settings-cache.c ++++ b/src/lib-master/master-service-settings-cache.c +@@ -138,7 +138,7 @@ master_service_settings_cache_fix_input(struct master_service_settings_cache *ca + filter->remote_bits)) + found_rip = TRUE; + if (input->local_name != NULL && filter->local_name != NULL && +- dns_match_wildcard(input->local_name, filter->local_name)) ++ dns_match_wildcard(input->local_name, filter->local_name) == 0) + found_local_name = TRUE; + filter = filter->next; + }; diff -Nru dovecot-2.2.27/debian/patches/series dovecot-2.2.27/debian/patches/series --- dovecot-2.2.27/debian/patches/series 2018-01-31 16:32:21.000000000 +0000 +++ dovecot-2.2.27/debian/patches/series 2018-02-26 18:19:41.000000000 +0000 @@ -12,3 +12,15 @@ CVE-2017-2669 CVE-2017-15132.patch CVE-2017-15132-additional.patch +CVE-2017-14461/0001-lib-mail-rfc822-parser-Add-asserts-to-make-sure-pars.patch +CVE-2017-14461/0003-lib-mail-Fix-out-of-bounds-read-when-parsing-an-inva.patch +CVE-2017-14461/0004-lib-mail-Make-sure-parsers-don-t-accidentally-go-muc.patch +CVE-2017-14461/0005-lib-mail-Add-rfc822_parser_deinit.patch +CVE-2017-14461/0006-lib-mail-Refactor-code-to-make-the-next-commit-small.patch +CVE-2017-14461/0007-global-Call-rfc822_parser_deinit-wherever-possible.patch +CVE-2017-15130/0001-lib-dns-Move-before-lib-master.patch +CVE-2017-15130/0002-config-Add-config_filter_get_all.patch +CVE-2017-15130/0003-config-Add-command-to-request-all-filters.patch +CVE-2017-15130/0004-lib-master-Support-validating-config-filters-against.patch +CVE-2017-15130/0005-login-common-Enable-config-filtering-by-local-name.patch +CVE-2017-15130/0006-lib-master-Fix-dns_match_wildcard-result-value-check.patch diff -Nru dovecot-2.2.27/debian/rules dovecot-2.2.27/debian/rules --- dovecot-2.2.27/debian/rules 2017-04-28 09:09:58.000000000 +0000 +++ dovecot-2.2.27/debian/rules 2018-02-26 18:19:51.000000000 +0000 @@ -69,7 +69,11 @@ usr/share/aclocal/*.m4 %: - dh $@ --with=systemd,autotools-dev + dh $@ --with=systemd,autoreconf + +override_dh_autoreconf: + mkdir m4 + dh_autoreconf override_dh_auto_configure: KRB5CONFIG=krb5-config.mit ./configure \