diff options
Diffstat (limited to 'mail-mta/exim/files/exim-4.97-CVE-2023-51766.patch')
-rw-r--r-- | mail-mta/exim/files/exim-4.97-CVE-2023-51766.patch | 265 |
1 files changed, 0 insertions, 265 deletions
diff --git a/mail-mta/exim/files/exim-4.97-CVE-2023-51766.patch b/mail-mta/exim/files/exim-4.97-CVE-2023-51766.patch deleted file mode 100644 index 7eed4eb1855f..000000000000 --- a/mail-mta/exim/files/exim-4.97-CVE-2023-51766.patch +++ /dev/null @@ -1,265 +0,0 @@ -https://nvd.nist.gov/vuln/detail/CVE-2023-51766 - - -From cf1376206284f2a4f11e32d931d4aade34c206c5 Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Fri, 22 Dec 2023 23:57:05 +0000 -Subject: [PATCH] Reject "dot, LF" as ending data phase. Bug 3063 - -From 5bb786d5ad568a88d50d15452aacc8404047e5ca Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Sat, 23 Dec 2023 17:42:57 +0000 -Subject: [PATCH] Reject "dot, LF" as ending data phase (pt. 2). Bug 3063 - -reduced to source changes only for Gentoo - - - -diff --git a/src/src/receive.c b/src/src/receive.c -index e35400aec..c6f612832 100644 ---- a/src/src/receive.c -+++ b/src/src/receive.c -@@ -836,93 +842,101 @@ - */ - - static int --read_message_data_smtp(FILE *fout) -+read_message_data_smtp(FILE * fout, BOOL strict_crlf) - { --int ch_state = 0; --int ch; --int linelength = 0; -+enum { s_linestart, s_normal, s_had_cr, s_had_nl_dot, s_had_dot_cr } ch_state = -+ s_linestart; -+int linelength = 0, ch; - - while ((ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF) - { - if (ch == 0) body_zerocount++; - switch (ch_state) - { -- case 0: /* After LF or CRLF */ -- if (ch == '.') -- { -- ch_state = 3; -- continue; /* Don't ever write . after LF */ -- } -- ch_state = 1; -+ case s_linestart: /* After LF or CRLF */ -+ if (ch == '.') -+ { -+ ch_state = s_had_nl_dot; -+ continue; /* Don't ever write . after LF */ -+ } -+ ch_state = s_normal; - -- /* Else fall through to handle as normal uschar. */ -+ /* Else fall through to handle as normal uschar. */ - -- case 1: /* Normal state */ -- if (ch == '\n') -- { -- ch_state = 0; -- body_linecount++; -+ case s_normal: /* Normal state */ -+ if (ch == '\r') -+ { -+ ch_state = s_had_cr; -+ continue; /* Don't write the CR */ -+ } -+ if (ch == '\n') /* Bare LF at end of line */ -+ if (strict_crlf) -+ ch = ' '; /* replace LF with space */ -+ else -+ { /* treat as line ending */ -+ ch_state = s_linestart; -+ body_linecount++; -+ if (linelength > max_received_linelength) -+ max_received_linelength = linelength; -+ linelength = -1; -+ } -+ break; -+ -+ case s_had_cr: /* After (unwritten) CR */ -+ body_linecount++; /* Any char ends line */ - if (linelength > max_received_linelength) -- max_received_linelength = linelength; -+ max_received_linelength = linelength; - linelength = -1; -- } -- else if (ch == '\r') -- { -- ch_state = 2; -- continue; -- } -- break; -+ if (ch == '\n') /* proper CRLF */ -+ ch_state = s_linestart; -+ else -+ { -+ message_size++; /* convert the dropped CR to a stored NL */ -+ if (fout && fputc('\n', fout) == EOF) return END_WERROR; -+ cutthrough_data_put_nl(); -+ if (ch == '\r') /* CR; do not write */ -+ continue; -+ ch_state = s_normal; /* not LF or CR; process as standard */ -+ } -+ break; - -- case 2: /* After (unwritten) CR */ -- body_linecount++; -- if (linelength > max_received_linelength) -- max_received_linelength = linelength; -- linelength = -1; -- if (ch == '\n') -- { -- ch_state = 0; -- } -- else -- { -- message_size++; -- if (fout != NULL && fputc('\n', fout) == EOF) return END_WERROR; -- cutthrough_data_put_nl(); -- if (ch != '\r') ch_state = 1; else continue; -- } -- break; -+ case s_had_nl_dot: /* After [CR] LF . */ -+ if (ch == '\n') /* [CR] LF . LF */ -+ if (strict_crlf) -+ ch = ' '; /* replace LF with space */ -+ else -+ return END_DOT; -+ else if (ch == '\r') /* [CR] LF . CR */ -+ { -+ ch_state = s_had_dot_cr; -+ continue; /* Don't write the CR */ -+ } -+ /* The dot was removed on reaching s_had_nl_dot. For a doubled dot, here, -+ reinstate it to cutthrough. The current ch, dot or not, is passed both to -+ cutthrough and to file below. */ -+ else if (ch == '.') -+ { -+ uschar c = ch; -+ cutthrough_data_puts(&c, 1); -+ } -+ ch_state = s_normal; -+ break; - -- case 3: /* After [CR] LF . */ -- if (ch == '\n') -- return END_DOT; -- if (ch == '\r') -- { -- ch_state = 4; -- continue; -- } -- /* The dot was removed at state 3. For a doubled dot, here, reinstate -- it to cutthrough. The current ch, dot or not, is passed both to cutthrough -- and to file below. */ -- if (ch == '.') -- { -- uschar c= ch; -- cutthrough_data_puts(&c, 1); -- } -- ch_state = 1; -- break; -+ case s_had_dot_cr: /* After [CR] LF . CR */ -+ if (ch == '\n') -+ return END_DOT; /* Preferred termination */ - -- case 4: /* After [CR] LF . CR */ -- if (ch == '\n') return END_DOT; -- message_size++; -- body_linecount++; -- if (fout != NULL && fputc('\n', fout) == EOF) return END_WERROR; -- cutthrough_data_put_nl(); -- if (ch == '\r') -- { -- ch_state = 2; -- continue; -- } -- ch_state = 1; -- break; -+ message_size++; /* convert the dropped CR to a stored NL */ -+ body_linecount++; -+ if (fout && fputc('\n', fout) == EOF) return END_WERROR; -+ cutthrough_data_put_nl(); -+ if (ch == '\r') -+ { -+ ch_state = s_had_cr; -+ continue; /* CR; do not write */ -+ } -+ ch_state = s_normal; -+ break; - } - - /* Add the character to the spool file, unless skipping; then loop for the -@@ -1140,7 +1152,7 @@ receive_swallow_smtp(void) - { - if (message_ended >= END_NOTENDED) - message_ended = chunking_state <= CHUNKING_OFFERED -- ? read_message_data_smtp(NULL) -+ ? read_message_data_smtp(NULL, FALSE) - : read_message_bdat_smtp_wire(NULL); - } - -@@ -1960,8 +1960,10 @@ for (;;) - - if (ch == '\n') - { -- if (first_line_ended_crlf == TRUE_UNSET) first_line_ended_crlf = FALSE; -- else if (first_line_ended_crlf) receive_ungetc(' '); -+ if (first_line_ended_crlf == TRUE_UNSET) -+ first_line_ended_crlf = FALSE; -+ else if (first_line_ended_crlf) -+ receive_ungetc(' '); - goto EOL; - } - -@@ -1977,7 +1980,11 @@ for (;;) - if (f.dot_ends && ptr == 0 && ch == '.') - { - ch = (receive_getc)(GETC_BUFFER_UNLIMITED); -- if (ch == '\r') -+ if (ch == '\n' && first_line_ended_crlf == TRUE /* and not TRUE_UNSET */ ) -+ /* dot, LF but we are in CRLF mode. Attack? */ -+ ch = ' '; /* replace the LF with a space */ -+ -+ else if (ch == '\r') - { - ch = (receive_getc)(GETC_BUFFER_UNLIMITED); - if (ch != '\n') -@@ -2013,7 +2020,8 @@ for (;;) - ch = (receive_getc)(GETC_BUFFER_UNLIMITED); - if (ch == '\n') - { -- if (first_line_ended_crlf == TRUE_UNSET) first_line_ended_crlf = TRUE; -+ if (first_line_ended_crlf == TRUE_UNSET) -+ first_line_ended_crlf = TRUE; - goto EOL; - } - -@@ -3241,7 +3253,7 @@ if (!ferror(spool_data_file) && !(receive_feof)() && message_ended != END_DOT) - if (smtp_input) - { - message_ended = chunking_state <= CHUNKING_OFFERED -- ? read_message_data_smtp(spool_data_file) -+ ? read_message_data_smtp(spool_data_file, first_line_ended_crlf) - : spool_wireformat - ? read_message_bdat_smtp_wire(spool_data_file) - : read_message_bdat_smtp(spool_data_file); -diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c -index e19c86ff8..aeaffeb37 100644 ---- a/src/src/smtp_in.c -+++ b/src/src/smtp_in.c -@@ -5112,7 +5112,10 @@ while (done <= 0) - to get the DATA command sent. */ - - if (!acl_smtp_predata && cutthrough.cctx.sock < 0) -+ { -+ if (!check_sync()) goto SYNC_FAILURE; - rc = OK; -+ } - else - { - uschar * acl = acl_smtp_predata ? acl_smtp_predata : US"accept"; |