diff -Nru postfix-3.6.4/debian/changelog postfix-3.6.4/debian/changelog --- postfix-3.6.4/debian/changelog 2023-04-10 11:35:27.000000000 +0000 +++ postfix-3.6.4/debian/changelog 2024-01-16 15:11:43.000000000 +0000 @@ -1,3 +1,14 @@ +postfix (3.6.4-1ubuntu1.2) jammy-security; urgency=medium + + * SECURITY UPDATE: SMTP smuggling (LP: #2049337) + - debian/patches/CVE-2023-51764.patch: introduced + `smtpd_forbid_bare_newline`. With "smtpd_forbid_bare_newline = yes", + the Postfix SMTP server disconnects a remote SMTP client that + sends a line ending in a 'bare newline'. + - CVE-2023-51764 + + -- Allen Huang Tue, 16 Jan 2024 15:11:43 +0000 + postfix (3.6.4-1ubuntu1.1) jammy; urgency=medium * d/p/1995312-unexpected-eof-fix.patch: Workaround for a breaking diff -Nru postfix-3.6.4/debian/patches/CVE-2023-51764.patch postfix-3.6.4/debian/patches/CVE-2023-51764.patch --- postfix-3.6.4/debian/patches/CVE-2023-51764.patch 1970-01-01 00:00:00.000000000 +0000 +++ postfix-3.6.4/debian/patches/CVE-2023-51764.patch 2024-01-16 15:11:43.000000000 +0000 @@ -0,0 +1,373 @@ +From a6596ec37a4892e1d9c2498ecbfc4b8e6be5156a Mon Sep 17 00:00:00 2001 +From: Wietse Venema +Date: Fri, 22 Dec 2023 00:00:00 -0500 +Subject: [PATCH] postfix-3.6.13 +--- + man/man5/postconf.5 | 55 +++++++++++++++++++++++++++++++++++++++++++++++ + man/man8/smtpd.8 | 9 +++++++ + mantools/postlink | 2 + + proto/postconf.proto | 52 ++++++++++++++++++++++++++++++++++++++++++++ + src/global/mail_params.h | 11 ++++++++- + src/global/smtp_stream.c | 14 +++++++++++ + src/global/smtp_stream.h | 2 + + src/smtpd/smtpd.c | 42 +++++++++++++++++++++++++++++++++++ + 8 files changed, 185 insertions(+), 2 deletions(-) + +--- a/man/man5/postconf.5 ++++ b/man/man5/postconf.5 +@@ -10412,6 +10412,61 @@ + parameter $name expansion. + .PP + This feature is available in Postfix 2.0 and later. ++.SH smtpd_forbid_bare_newline (default: Postfix < 3.9: no) ++Reply with "Error: bare received" and disconnect ++when a remote SMTP client sends a line ending in , violating ++the RFC 5321 requirement that lines must end in . ++This feature is disbled by default with Postfix < 3.9. Use ++smtpd_forbid_bare_newline_exclusions to exclude non\-standard clients ++such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable ++(not recommended for an Internet\-connected MTA). ++.PP ++See ++https://www.postfix.org/smtp\-smuggling.html for details. ++.PP ++Example: ++.sp ++.in +4 ++.nf ++.na ++.ft C ++# Disconnect remote SMTP clients that send bare newlines, but allow ++# local clients with non\-standard SMTP implementations such as netcat, ++# fax machines, or load balancer health checks. ++# ++smtpd_forbid_bare_newline = yes ++smtpd_forbid_bare_newline_exclusions = $mynetworks ++.fi ++.ad ++.ft R ++.in -4 ++.PP ++This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9, ++3.6.13, and 3.5.23. ++.SH smtpd_forbid_bare_newline_exclusions (default: $mynetworks) ++Exclude the specified clients from smtpd_forbid_bare_newline ++enforcement. It uses the same syntax and parent\-domain matching ++behavior as mynetworks. ++.PP ++Example: ++.sp ++.in +4 ++.nf ++.na ++.ft C ++# Disconnect remote SMTP clients that send bare newlines, but allow ++# local clients with non\-standard SMTP implementations such as netcat, ++# fax machines, or load balancer health checks. ++# ++smtpd_forbid_bare_newline = yes ++smtpd_forbid_bare_newline_exclusions = $mynetworks ++.fi ++.ad ++.ft R ++.in -4 ++.PP ++This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9, ++3.6.13, and 3.5.23. + .SH smtpd_forbidden_commands (default: CONNECT, GET, POST) + List of commands that cause the Postfix SMTP server to immediately + terminate the session with a 221 code. This can be used to disconnect +--- a/man/man8/smtpd.8 ++++ b/man/man8/smtpd.8 +@@ -808,6 +808,15 @@ + The maximal number of AUTH commands that any client is allowed to + send to this service per time unit, regardless of whether or not + Postfix actually accepts those commands. ++.PP ++Available in Postfix 3.9, 3.8.4, 3.7.9, 3.6.13, 3.5.23 and later: ++.IP "\fBsmtpd_forbid_bare_newline (Postfix < 3.9: no)\fR" ++Reply with "Error: bare received" and disconnect ++when a remote SMTP client sends a line ending in , violating ++the RFC 5321 requirement that lines must end in . ++.IP "\fBsmtpd_forbid_bare_newline_exclusions ($mynetworks)\fR" ++Exclude the specified clients from smtpd_forbid_bare_newline ++enforcement. + .SH "TARPIT CONTROLS" + .na + .nf +--- a/mantools/postlink ++++ b/mantools/postlink +@@ -547,6 +547,8 @@ + s;\bsmtpd_error_sleep_time\b;$&;g; + s;\bsmtpd_etrn_restrictions\b;$&;g; + s;\bsmtpd_expansion_filter\b;$&;g; ++ s;\bsmtpd_for[-]*\n*[ ]*bid_bare_newline\b;$&;g; ++ s;\bsmtpd_for[-]*\n*[ ]*bid_bare_newline_exclusions\b;$&;g; + s;\bsmtpd_for[-]*\n*[ ]*bidden_commands\b;$&;g; + s;\bsmtpd_hard_error_limit\b;$&;g; + s;\bsmtpd_helo_required\b;$&;g; +--- a/proto/postconf.proto ++++ b/proto/postconf.proto +@@ -18058,3 +18058,55 @@ + name or port number.

+ +

This feature is available in Postfix 3.6 and later.

++ ++%PARAM smtpd_forbid_bare_newline Postfix < 3.9: no ++ ++

Reply with "Error: bare <LF> received" and disconnect ++when a remote SMTP client sends a line ending in <LF>, violating ++the RFC 5321 requirement that lines must end in <CR><LF>. ++This feature is disbled by default with Postfix < 3.9. Use ++smtpd_forbid_bare_newline_exclusions to exclude non-standard clients ++such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable ++(not recommended for an Internet-connected MTA).

++ ++

See ++https://www.postfix.org/smtp-smuggling.html for details. ++ ++

Example:

++ ++
++
++# Disconnect remote SMTP clients that send bare newlines, but allow
++# local clients with non-standard SMTP implementations such as netcat,
++# fax machines, or load balancer health checks.
++#
++smtpd_forbid_bare_newline = yes
++smtpd_forbid_bare_newline_exclusions = $mynetworks
++
++
++ ++

This feature is available in Postfix ≥ 3.9, 3.8.4, 3.7.9, ++3.6.13, and 3.5.23.

++ ++%PARAM smtpd_forbid_bare_newline_exclusions $mynetworks ++ ++

Exclude the specified clients from smtpd_forbid_bare_newline ++enforcement. It uses the same syntax and parent-domain matching ++behavior as mynetworks.

++ ++

Example:

++ ++
++
++# Disconnect remote SMTP clients that send bare newlines, but allow
++# local clients with non-standard SMTP implementations such as netcat,
++# fax machines, or load balancer health checks.
++#
++smtpd_forbid_bare_newline = yes
++smtpd_forbid_bare_newline_exclusions = $mynetworks
++
++
++ ++

This feature is available in Postfix ≥ 3.9, 3.8.4, 3.7.9, ++3.6.13, and 3.5.23.

++ +--- a/src/global/mail_params.h ++++ b/src/global/mail_params.h +@@ -4170,7 +4170,16 @@ + extern char *var_smtpd_dns_re_filter; + + /* +- * Share TLS sessions through tlproxy(8). ++ * Backwards compatibility. ++ */ ++#define VAR_SMTPD_FORBID_BARE_LF "smtpd_forbid_bare_newline" ++#define DEF_SMTPD_FORBID_BARE_LF 0 ++ ++#define VAR_SMTPD_FORBID_BARE_LF_EXCL "smtpd_forbid_bare_newline_exclusions" ++#define DEF_SMTPD_FORBID_BARE_LF_EXCL "$" VAR_MYNETWORKS ++ ++ /* ++ * Share TLS sessions through tlsproxy(8). + */ + #define VAR_SMTP_TLS_CONN_REUSE "smtp_tls_connection_reuse" + #define DEF_SMTP_TLS_CONN_REUSE 0 +--- a/src/global/smtp_stream.c ++++ b/src/global/smtp_stream.c +@@ -50,6 +50,8 @@ + /* VSTREAM *stream; + /* char *format; + /* va_list ap; ++/* ++/* int smtp_forbid_bare_lf; + /* AUXILIARY API + /* int smtp_get_noexcept(vp, stream, maxlen, flags) + /* VSTRING *vp; +@@ -124,11 +126,16 @@ + /* smtp_vprintf() is the machine underneath smtp_printf(). + /* + /* smtp_get_noexcept() implements the subset of smtp_get() +-/* without timeouts and without making long jumps. Instead, ++/* without long jumps for timeout or EOF errors. Instead, + /* query the stream status with vstream_feof() etc. ++/* This function will make a VSTREAM long jump (error code ++/* SMTP_ERR_LF) when rejecting input with a bare newline byte. + /* + /* smtp_timeout_setup() is a backwards-compatibility interface + /* for programs that don't require per-record deadline support. ++/* ++/* smtp_forbid_bare_lf controls whether smtp_get_noexcept() ++/* will reject input with a bare newline byte. + /* DIAGNOSTICS + /* .fi + /* .ad +@@ -201,6 +208,8 @@ + + #include "smtp_stream.h" + ++int smtp_forbid_bare_lf; ++ + /* smtp_timeout_reset - reset per-stream error flags, restart deadline timer */ + + static void smtp_timeout_reset(VSTREAM *stream) +@@ -404,6 +413,9 @@ + */ + case '\n': + vstring_truncate(vp, VSTRING_LEN(vp) - 1); ++ if (smtp_forbid_bare_lf ++ && (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r')) ++ vstream_longjmp(stream, SMTP_ERR_LF); + while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r') + vstring_truncate(vp, VSTRING_LEN(vp) - 1); + VSTRING_TERMINATE(vp); +--- a/src/global/smtp_stream.h ++++ b/src/global/smtp_stream.h +@@ -32,6 +32,7 @@ + #define SMTP_ERR_QUIET 3 /* silent cleanup (application) */ + #define SMTP_ERR_NONE 4 /* non-error case */ + #define SMTP_ERR_DATA 5 /* application data error */ ++#define SMTP_ERR_LF 6 /* bare protocol error */ + + extern void smtp_stream_setup(VSTREAM *, int, int); + extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...); +@@ -43,6 +44,7 @@ + extern void smtp_fwrite(const char *, ssize_t len, VSTREAM *); + extern void smtp_fread_buf(VSTRING *, ssize_t len, VSTREAM *); + extern void smtp_fputc(int, VSTREAM *); ++extern int smtp_forbid_bare_lf; + + extern void smtp_vprintf(VSTREAM *, const char *, va_list); + +--- a/src/smtpd/smtpd.c ++++ b/src/smtpd/smtpd.c +@@ -762,6 +762,15 @@ + /* The maximal number of AUTH commands that any client is allowed to + /* send to this service per time unit, regardless of whether or not + /* Postfix actually accepts those commands. ++/* .PP ++/* Available in Postfix 3.9, 3.8.4, 3.7.9, 3.6.13, 3.5.23 and later: ++/* .IP "\fBsmtpd_forbid_bare_newline (Postfix < 3.9: no)\fR" ++/* Reply with "Error: bare received" and disconnect ++/* when a remote SMTP client sends a line ending in , violating ++/* the RFC 5321 requirement that lines must end in . ++/* .IP "\fBsmtpd_forbid_bare_newline_exclusions ($mynetworks)\fR" ++/* Exclude the specified clients from smtpd_forbid_bare_newline ++/* enforcement. + /* TARPIT CONTROLS + /* .ad + /* .fi +@@ -1467,6 +1476,10 @@ + int var_smtpd_uproxy_tmout; + bool var_relay_before_rcpt_checks; + ++bool var_smtpd_forbid_bare_lf; ++char *var_smtpd_forbid_bare_lf_excl; ++static NAMADR_LIST *bare_lf_excl; ++ + /* + * Silly little macros. + */ +@@ -1541,6 +1554,7 @@ + #define REASON_TIMEOUT "timeout" + #define REASON_LOST_CONNECTION "lost connection" + #define REASON_ERROR_LIMIT "too many errors" ++#define REASON_BARE_LF "bare received" + + #ifdef USE_TLS + +@@ -3967,6 +3981,7 @@ + */ + done = 0; + do { ++ int payload_err; + + /* + * Do not skip the smtp_fread_buf() call if read_len == 0. We still +@@ -3980,6 +3995,10 @@ + smtp_fread_buf(state->buffer, read_len, state->client); + state->bdat_get_stream = vstream_memreopen( + state->bdat_get_stream, state->buffer, O_RDONLY); ++ vstream_control(state->bdat_get_stream, CA_VSTREAM_CTL_EXCEPT, ++ CA_VSTREAM_CTL_END); ++ if ((payload_err = vstream_setjmp(state->bdat_get_stream)) != 0) ++ vstream_longjmp(state->client, payload_err); + + /* + * Read lines from the fragment. The last line may continue in the +@@ -4655,6 +4674,9 @@ + */ + xclient_allowed = + namadr_list_match(xclient_hosts, state->name, state->addr); ++ smtp_forbid_bare_lf = SMTPD_STAND_ALONE((state)) == 0 ++ && var_smtpd_forbid_bare_lf ++ && !namadr_list_match(bare_lf_excl, state->name, state->addr); + /* NOT: tls_reset() */ + if (got_helo == 0) + helo_reset(state); +@@ -5446,6 +5468,13 @@ + var_myhostname); + break; + ++ case SMTP_ERR_LF: ++ state->reason = REASON_BARE_LF; ++ if (vstream_setjmp(state->client) == 0) ++ smtpd_chat_reply(state, "521 5.5.2 %s Error: bare received", ++ var_myhostname); ++ break; ++ + case 0: + + /* +@@ -5995,6 +6024,13 @@ + namadr_list_match(xforward_hosts, state.name, state.addr); + + /* ++ * Enforce strict SMTP line endings, with compatibility exclusions. ++ */ ++ smtp_forbid_bare_lf = SMTPD_STAND_ALONE((&state)) == 0 ++ && var_smtpd_forbid_bare_lf ++ && !namadr_list_match(bare_lf_excl, state.name, state.addr); ++ ++ /* + * See if we need to turn on verbose logging for this client. + */ + debug_peer_check(state.name, state.addr); +@@ -6055,6 +6091,10 @@ + hogger_list = namadr_list_init(VAR_SMTPD_HOGGERS, MATCH_FLAG_RETURN + | match_parent_style(VAR_SMTPD_HOGGERS), + var_smtpd_hoggers); ++ bare_lf_excl = namadr_list_init(VAR_SMTPD_FORBID_BARE_LF_EXCL, ++ MATCH_FLAG_RETURN ++ | match_parent_style(VAR_MYNETWORKS), ++ var_smtpd_forbid_bare_lf_excl); + + /* + * Open maps before dropping privileges so we can read passwords etc. +@@ -6412,6 +6452,7 @@ + VAR_SMTPD_PEERNAME_LOOKUP, DEF_SMTPD_PEERNAME_LOOKUP, &var_smtpd_peername_lookup, + VAR_SMTPD_DELAY_OPEN, DEF_SMTPD_DELAY_OPEN, &var_smtpd_delay_open, + VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, &var_smtpd_client_port_log, ++ VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, &var_smtpd_forbid_bare_lf, + 0, + }; + static const CONFIG_NBOOL_TABLE nbool_table[] = { +@@ -6527,6 +6568,7 @@ + VAR_SMTPD_POLICY_CONTEXT, DEF_SMTPD_POLICY_CONTEXT, &var_smtpd_policy_context, 0, 0, + VAR_SMTPD_DNS_RE_FILTER, DEF_SMTPD_DNS_RE_FILTER, &var_smtpd_dns_re_filter, 0, 0, + VAR_SMTPD_REJ_FTR_MAPS, DEF_SMTPD_REJ_FTR_MAPS, &var_smtpd_rej_ftr_maps, 0, 0, ++ VAR_SMTPD_FORBID_BARE_LF_EXCL, DEF_SMTPD_FORBID_BARE_LF_EXCL, &var_smtpd_forbid_bare_lf_excl, 0, 0, + 0, + }; + static const CONFIG_RAW_TABLE raw_table[] = { diff -Nru postfix-3.6.4/debian/patches/series postfix-3.6.4/debian/patches/series --- postfix-3.6.4/debian/patches/series 2023-03-30 02:11:18.000000000 +0000 +++ postfix-3.6.4/debian/patches/series 2024-01-16 14:06:50.000000000 +0000 @@ -16,3 +16,4 @@ postfix-3.6.2-glibc-234-build-fix.patch 1995312-unexpected-eof-fix.patch 1996524-Linux6-support.patch +CVE-2023-51764.patch