Skip to content

Commit 667850f

Browse files
Ashish Sharmaakuster
authored andcommitted
postfix: Backport fix for CVE-2023-51764
Import patches from ubuntu launchpad fix CVE-2023-51764 Upstream-Status: Backport from [https://launchpad.net/ubuntu/+source/postfix/3.6.4-1ubuntu1.3] Signed-off-by: Ashish Sharma <asharma@mvista.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
1 parent f81b181 commit 667850f

3 files changed

Lines changed: 1357 additions & 0 deletions

File tree

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
From a6596ec37a4892e1d9c2498ecbfc4b8e6be5156a Mon Sep 17 00:00:00 2001
2+
From: Wietse Venema <wietse@porcupine.org>
3+
Date: Fri, 22 Dec 2023 00:00:00 -0500
4+
Subject: [PATCH] postfix-3.6.13
5+
---
6+
Upstream-Status: Backport from [https://launchpad.net/ubuntu/+source/postfix/3.6.4-1ubuntu1.3]
7+
CVE: CVE-2023-51764
8+
Signed-off-by: Ashish Sharma <asharma@mvista.com>
9+
10+
man/man5/postconf.5 | 55 +++++++++++++++++++++++++++++++++++++++++++++++
11+
man/man8/smtpd.8 | 9 +++++++
12+
mantools/postlink | 2 +
13+
proto/postconf.proto | 52 ++++++++++++++++++++++++++++++++++++++++++++
14+
src/global/mail_params.h | 11 ++++++++-
15+
src/global/smtp_stream.c | 14 +++++++++++
16+
src/global/smtp_stream.h | 2 +
17+
src/smtpd/smtpd.c | 42 +++++++++++++++++++++++++++++++++++
18+
8 files changed, 185 insertions(+), 2 deletions(-)
19+
20+
--- a/man/man5/postconf.5
21+
+++ b/man/man5/postconf.5
22+
@@ -10412,6 +10412,61 @@
23+
parameter $name expansion.
24+
.PP
25+
This feature is available in Postfix 2.0 and later.
26+
+.SH smtpd_forbid_bare_newline (default: Postfix < 3.9: no)
27+
+Reply with "Error: bare <LF> received" and disconnect
28+
+when a remote SMTP client sends a line ending in <LF>, violating
29+
+the RFC 5321 requirement that lines must end in <CR><LF>.
30+
+This feature is disbled by default with Postfix < 3.9. Use
31+
+smtpd_forbid_bare_newline_exclusions to exclude non\-standard clients
32+
+such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable
33+
+(not recommended for an Internet\-connected MTA).
34+
+.PP
35+
+See
36+
+https://www.postfix.org/smtp\-smuggling.html for details.
37+
+.PP
38+
+Example:
39+
+.sp
40+
+.in +4
41+
+.nf
42+
+.na
43+
+.ft C
44+
+# Disconnect remote SMTP clients that send bare newlines, but allow
45+
+# local clients with non\-standard SMTP implementations such as netcat,
46+
+# fax machines, or load balancer health checks.
47+
+#
48+
+smtpd_forbid_bare_newline = yes
49+
+smtpd_forbid_bare_newline_exclusions = $mynetworks
50+
+.fi
51+
+.ad
52+
+.ft R
53+
+.in -4
54+
+.PP
55+
+This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9,
56+
+3.6.13, and 3.5.23.
57+
+.SH smtpd_forbid_bare_newline_exclusions (default: $mynetworks)
58+
+Exclude the specified clients from smtpd_forbid_bare_newline
59+
+enforcement. It uses the same syntax and parent\-domain matching
60+
+behavior as mynetworks.
61+
+.PP
62+
+Example:
63+
+.sp
64+
+.in +4
65+
+.nf
66+
+.na
67+
+.ft C
68+
+# Disconnect remote SMTP clients that send bare newlines, but allow
69+
+# local clients with non\-standard SMTP implementations such as netcat,
70+
+# fax machines, or load balancer health checks.
71+
+#
72+
+smtpd_forbid_bare_newline = yes
73+
+smtpd_forbid_bare_newline_exclusions = $mynetworks
74+
+.fi
75+
+.ad
76+
+.ft R
77+
+.in -4
78+
+.PP
79+
+This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9,
80+
+3.6.13, and 3.5.23.
81+
.SH smtpd_forbidden_commands (default: CONNECT, GET, POST)
82+
List of commands that cause the Postfix SMTP server to immediately
83+
terminate the session with a 221 code. This can be used to disconnect
84+
--- a/man/man8/smtpd.8
85+
+++ b/man/man8/smtpd.8
86+
@@ -808,6 +808,15 @@
87+
The maximal number of AUTH commands that any client is allowed to
88+
send to this service per time unit, regardless of whether or not
89+
Postfix actually accepts those commands.
90+
+.PP
91+
+Available in Postfix 3.9, 3.8.4, 3.7.9, 3.6.13, 3.5.23 and later:
92+
+.IP "\fBsmtpd_forbid_bare_newline (Postfix < 3.9: no)\fR"
93+
+Reply with "Error: bare <LF> received" and disconnect
94+
+when a remote SMTP client sends a line ending in <LF>, violating
95+
+the RFC 5321 requirement that lines must end in <CR><LF>.
96+
+.IP "\fBsmtpd_forbid_bare_newline_exclusions ($mynetworks)\fR"
97+
+Exclude the specified clients from smtpd_forbid_bare_newline
98+
+enforcement.
99+
.SH "TARPIT CONTROLS"
100+
.na
101+
.nf
102+
--- a/mantools/postlink
103+
+++ b/mantools/postlink
104+
@@ -547,6 +547,8 @@
105+
s;\bsmtpd_error_sleep_time\b;<a href="postconf.5.html#smtpd_error_sleep_time">$&</a>;g;
106+
s;\bsmtpd_etrn_restrictions\b;<a href="postconf.5.html#smtpd_etrn_restrictions">$&</a>;g;
107+
s;\bsmtpd_expansion_filter\b;<a href="postconf.5.html#smtpd_expansion_filter">$&</a>;g;
108+
+ s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_bare_newline\b;<a href="postconf.5.html#smtpd_forbi d_bare_newline">$&</a>;g;
109+
+ s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_bare_newline_exclusions\b;<a href="postconf.5.html# smtpd_forbid_bare_newline_exclusions">$&</a>;g;
110+
s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bidden_commands\b;<a href="postconf.5.html#smtpd_forbidden_commands">$&</a>;g;
111+
s;\bsmtpd_hard_error_limit\b;<a href="postconf.5.html#smtpd_hard_error_limit">$&</a>;g;
112+
s;\bsmtpd_helo_required\b;<a href="postconf.5.html#smtpd_helo_required">$&</a>;g;
113+
--- a/proto/postconf.proto
114+
+++ b/proto/postconf.proto
115+
@@ -18058,3 +18058,55 @@
116+
name or port number. </p>
117+
118+
<p> This feature is available in Postfix 3.6 and later. </p>
119+
+
120+
+%PARAM smtpd_forbid_bare_newline Postfix &lt; 3.9: no
121+
+
122+
+<p> Reply with "Error: bare &lt;LF&gt; received" and disconnect
123+
+when a remote SMTP client sends a line ending in &lt;LF&gt;, violating
124+
+the RFC 5321 requirement that lines must end in &lt;CR&gt;&lt;LF&gt;.
125+
+This feature is disbled by default with Postfix &lt; 3.9. Use
126+
+smtpd_forbid_bare_newline_exclusions to exclude non-standard clients
127+
+such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable
128+
+(not recommended for an Internet-connected MTA). </p>
129+
+
130+
+<p> See <a href="https://www.postfix.org/smtp-smuggling.html">
131+
+https://www.postfix.org/smtp-smuggling.html</a> for details.
132+
+
133+
+<p> Example: </p>
134+
+
135+
+<blockquote>
136+
+<pre>
137+
+# Disconnect remote SMTP clients that send bare newlines, but allow
138+
+# local clients with non-standard SMTP implementations such as netcat,
139+
+# fax machines, or load balancer health checks.
140+
+#
141+
+smtpd_forbid_bare_newline = yes
142+
+smtpd_forbid_bare_newline_exclusions = $mynetworks
143+
+</pre>
144+
+</blockquote>
145+
+
146+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.4, 3.7.9,
147+
+3.6.13, and 3.5.23. </p>
148+
+
149+
+%PARAM smtpd_forbid_bare_newline_exclusions $mynetworks
150+
+
151+
+<p> Exclude the specified clients from smtpd_forbid_bare_newline
152+
+enforcement. It uses the same syntax and parent-domain matching
153+
+behavior as mynetworks. </p>
154+
+
155+
+<p> Example: </p>
156+
+
157+
+<blockquote>
158+
+<pre>
159+
+# Disconnect remote SMTP clients that send bare newlines, but allow
160+
+# local clients with non-standard SMTP implementations such as netcat,
161+
+# fax machines, or load balancer health checks.
162+
+#
163+
+smtpd_forbid_bare_newline = yes
164+
+smtpd_forbid_bare_newline_exclusions = $mynetworks
165+
+</pre>
166+
+</blockquote>
167+
+
168+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.4, 3.7.9,
169+
+3.6.13, and 3.5.23. </p>
170+
+
171+
--- a/src/global/mail_params.h
172+
+++ b/src/global/mail_params.h
173+
@@ -4170,7 +4170,16 @@
174+
extern char *var_smtpd_dns_re_filter;
175+
176+
/*
177+
- * Share TLS sessions through tlproxy(8).
178+
+ * Backwards compatibility.
179+
+ */
180+
+#define VAR_SMTPD_FORBID_BARE_LF "smtpd_forbid_bare_newline"
181+
+#define DEF_SMTPD_FORBID_BARE_LF 0
182+
+
183+
+#define VAR_SMTPD_FORBID_BARE_LF_EXCL "smtpd_forbid_bare_newline_exclusions"
184+
+#define DEF_SMTPD_FORBID_BARE_LF_EXCL "$" VAR_MYNETWORKS
185+
+
186+
+ /*
187+
+ * Share TLS sessions through tlsproxy(8).
188+
*/
189+
#define VAR_SMTP_TLS_CONN_REUSE "smtp_tls_connection_reuse"
190+
#define DEF_SMTP_TLS_CONN_REUSE 0
191+
--- a/src/global/smtp_stream.c
192+
+++ b/src/global/smtp_stream.c
193+
@@ -50,6 +50,8 @@
194+
/* VSTREAM *stream;
195+
/* char *format;
196+
/* va_list ap;
197+
+/*
198+
+/* int smtp_forbid_bare_lf;
199+
/* AUXILIARY API
200+
/* int smtp_get_noexcept(vp, stream, maxlen, flags)
201+
/* VSTRING *vp;
202+
@@ -124,11 +126,16 @@
203+
/* smtp_vprintf() is the machine underneath smtp_printf().
204+
/*
205+
/* smtp_get_noexcept() implements the subset of smtp_get()
206+
-/* without timeouts and without making long jumps. Instead,
207+
+/* without long jumps for timeout or EOF errors. Instead,
208+
/* query the stream status with vstream_feof() etc.
209+
+/* This function will make a VSTREAM long jump (error code
210+
+/* SMTP_ERR_LF) when rejecting input with a bare newline byte.
211+
/*
212+
/* smtp_timeout_setup() is a backwards-compatibility interface
213+
/* for programs that don't require per-record deadline support.
214+
+/*
215+
+/* smtp_forbid_bare_lf controls whether smtp_get_noexcept()
216+
+/* will reject input with a bare newline byte.
217+
/* DIAGNOSTICS
218+
/* .fi
219+
/* .ad
220+
@@ -201,6 +208,8 @@
221+
222+
#include "smtp_stream.h"
223+
224+
+int smtp_forbid_bare_lf;
225+
+
226+
/* smtp_timeout_reset - reset per-stream error flags, restart deadline timer */
227+
228+
static void smtp_timeout_reset(VSTREAM *stream)
229+
@@ -404,6 +413,9 @@
230+
*/
231+
case '\n':
232+
vstring_truncate(vp, VSTRING_LEN(vp) - 1);
233+
+ if (smtp_forbid_bare_lf
234+
+ && (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r'))
235+
+ vstream_longjmp(stream, SMTP_ERR_LF);
236+
while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r')
237+
vstring_truncate(vp, VSTRING_LEN(vp) - 1);
238+
VSTRING_TERMINATE(vp);
239+
--- a/src/global/smtp_stream.h
240+
+++ b/src/global/smtp_stream.h
241+
@@ -32,6 +32,7 @@
242+
#define SMTP_ERR_QUIET 3 /* silent cleanup (application) */
243+
#define SMTP_ERR_NONE 4 /* non-error case */
244+
#define SMTP_ERR_DATA 5 /* application data error */
245+
+#define SMTP_ERR_LF 6 /* bare <LF> protocol error */
246+
247+
extern void smtp_stream_setup(VSTREAM *, int, int);
248+
extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...);
249+
@@ -43,6 +44,7 @@
250+
extern void smtp_fwrite(const char *, ssize_t len, VSTREAM *);
251+
extern void smtp_fread_buf(VSTRING *, ssize_t len, VSTREAM *);
252+
extern void smtp_fputc(int, VSTREAM *);
253+
+extern int smtp_forbid_bare_lf;
254+
255+
extern void smtp_vprintf(VSTREAM *, const char *, va_list);
256+
257+
--- a/src/smtpd/smtpd.c
258+
+++ b/src/smtpd/smtpd.c
259+
@@ -762,6 +762,15 @@
260+
/* The maximal number of AUTH commands that any client is allowed to
261+
/* send to this service per time unit, regardless of whether or not
262+
/* Postfix actually accepts those commands.
263+
+/* .PP
264+
+/* Available in Postfix 3.9, 3.8.4, 3.7.9, 3.6.13, 3.5.23 and later:
265+
+/* .IP "\fBsmtpd_forbid_bare_newline (Postfix < 3.9: no)\fR"
266+
+/* Reply with "Error: bare <LF> received" and disconnect
267+
+/* when a remote SMTP client sends a line ending in <LF>, violating
268+
+/* the RFC 5321 requirement that lines must end in <CR><LF>.
269+
+/* .IP "\fBsmtpd_forbid_bare_newline_exclusions ($mynetworks)\fR"
270+
+/* Exclude the specified clients from smtpd_forbid_bare_newline
271+
+/* enforcement.
272+
/* TARPIT CONTROLS
273+
/* .ad
274+
/* .fi
275+
@@ -1467,6 +1476,10 @@
276+
int var_smtpd_uproxy_tmout;
277+
bool var_relay_before_rcpt_checks;
278+
279+
+bool var_smtpd_forbid_bare_lf;
280+
+char *var_smtpd_forbid_bare_lf_excl;
281+
+static NAMADR_LIST *bare_lf_excl;
282+
+
283+
/*
284+
* Silly little macros.
285+
*/
286+
@@ -1541,6 +1554,7 @@
287+
#define REASON_TIMEOUT "timeout"
288+
#define REASON_LOST_CONNECTION "lost connection"
289+
#define REASON_ERROR_LIMIT "too many errors"
290+
+#define REASON_BARE_LF "bare <LF> received"
291+
292+
#ifdef USE_TLS
293+
294+
@@ -3967,6 +3981,7 @@
295+
*/
296+
done = 0;
297+
do {
298+
+ int payload_err;
299+
300+
/*
301+
* Do not skip the smtp_fread_buf() call if read_len == 0. We still
302+
@@ -3980,6 +3995,10 @@
303+
smtp_fread_buf(state->buffer, read_len, state->client);
304+
state->bdat_get_stream = vstream_memreopen(
305+
state->bdat_get_stream, state->buffer, O_RDONLY);
306+
+ vstream_control(state->bdat_get_stream, CA_VSTREAM_CTL_EXCEPT,
307+
+ CA_VSTREAM_CTL_END);
308+
+ if ((payload_err = vstream_setjmp(state->bdat_get_stream)) != 0)
309+
+ vstream_longjmp(state->client, payload_err);
310+
311+
/*
312+
* Read lines from the fragment. The last line may continue in the
313+
@@ -4655,6 +4674,9 @@
314+
*/
315+
xclient_allowed =
316+
namadr_list_match(xclient_hosts, state->name, state->addr);
317+
+ smtp_forbid_bare_lf = SMTPD_STAND_ALONE((state)) == 0
318+
+ && var_smtpd_forbid_bare_lf
319+
+ && !namadr_list_match(bare_lf_excl, state->name, state->addr);
320+
/* NOT: tls_reset() */
321+
if (got_helo == 0)
322+
helo_reset(state);
323+
@@ -5446,6 +5468,13 @@
324+
var_myhostname);
325+
break;
326+
327+
+ case SMTP_ERR_LF:
328+
+ state->reason = REASON_BARE_LF;
329+
+ if (vstream_setjmp(state->client) == 0)
330+
+ smtpd_chat_reply(state, "521 5.5.2 %s Error: bare <LF> received",
331+
+ var_myhostname);
332+
+ break;
333+
+
334+
case 0:
335+
336+
/*
337+
@@ -5995,6 +6024,13 @@
338+
namadr_list_match(xforward_hosts, state.name, state.addr);
339+
340+
/*
341+
+ * Enforce strict SMTP line endings, with compatibility exclusions.
342+
+ */
343+
+ smtp_forbid_bare_lf = SMTPD_STAND_ALONE((&state)) == 0
344+
+ && var_smtpd_forbid_bare_lf
345+
+ && !namadr_list_match(bare_lf_excl, state.name, state.addr);
346+
+
347+
+ /*
348+
* See if we need to turn on verbose logging for this client.
349+
*/
350+
debug_peer_check(state.name, state.addr);
351+
@@ -6055,6 +6091,10 @@
352+
hogger_list = namadr_list_init(VAR_SMTPD_HOGGERS, MATCH_FLAG_RETURN
353+
| match_parent_style(VAR_SMTPD_HOGGERS),
354+
var_smtpd_hoggers);
355+
+ bare_lf_excl = namadr_list_init(VAR_SMTPD_FORBID_BARE_LF_EXCL,
356+
+ MATCH_FLAG_RETURN
357+
+ | match_parent_style(VAR_MYNETWORKS),
358+
+ var_smtpd_forbid_bare_lf_excl);
359+
360+
/*
361+
* Open maps before dropping privileges so we can read passwords etc.
362+
@@ -6412,6 +6452,7 @@
363+
VAR_SMTPD_PEERNAME_LOOKUP, DEF_SMTPD_PEERNAME_LOOKUP, &var_smtpd_peername_lookup,
364+
VAR_SMTPD_DELAY_OPEN, DEF_SMTPD_DELAY_OPEN, &var_smtpd_delay_open,
365+
VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, &var_smtpd_client_port_log,
366+
+ VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, &var_smtpd_forbid_bare_lf,
367+
0,
368+
};
369+
static const CONFIG_NBOOL_TABLE nbool_table[] = {
370+
@@ -6527,6 +6568,7 @@
371+
VAR_SMTPD_POLICY_CONTEXT, DEF_SMTPD_POLICY_CONTEXT, &var_smtpd_policy_context, 0, 0,
372+
VAR_SMTPD_DNS_RE_FILTER, DEF_SMTPD_DNS_RE_FILTER, &var_smtpd_dns_re_filter, 0, 0,
373+
VAR_SMTPD_REJ_FTR_MAPS, DEF_SMTPD_REJ_FTR_MAPS, &var_smtpd_rej_ftr_maps, 0, 0,
374+
+ VAR_SMTPD_FORBID_BARE_LF_EXCL, DEF_SMTPD_FORBID_BARE_LF_EXCL, &var_smtpd_forbid_bare_lf_excl, 0, 0,
375+
0,
376+
};
377+
static const CONFIG_RAW_TABLE raw_table[] = {

0 commit comments

Comments
 (0)