commit:     38b56d6352c696749e20078af71daaf871e58691
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 25 10:39:54 2023 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Mon Dec 25 10:42:12 2023 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=38b56d63

mail-mta/exim: add backport for CVE-2023-51766 to 4.96 and 4.97

Addresses:
 Partially vulnerable to "SMTP Smuggling" if pipelining is enabled and
 chunking is disabled/unused

Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 mail-mta/exim/Manifest                             |   2 -
 .../{exim-4.97-r1.ebuild => exim-4.96-r5.ebuild}   |  33 ++-
 .../{exim-4.97-r1.ebuild => exim-4.97-r2.ebuild}   |   1 +
 mail-mta/exim/files/exim-4.97-CVE-2023-51766.patch | 265 +++++++++++++++++++++
 4 files changed, 294 insertions(+), 7 deletions(-)

diff --git a/mail-mta/exim/Manifest b/mail-mta/exim/Manifest
index 2422a76d59b8..897713920daf 100644
--- a/mail-mta/exim/Manifest
+++ b/mail-mta/exim/Manifest
@@ -1,9 +1,7 @@
-DIST exim-4.94.2.tar.xz 1838076 BLAKE2B 
684e115a7af3efdab15451f8e11f9b53455c9166d8c078216d7a95223d77569cec8a882ed99b9180acbd8a9e747a0bca03d56993d011de15dc35143a989ab046
 SHA512 
5334c236221ed4e03dbc33e6a79d939b06037fa2f4b71971607a360b67af5c85a89681ee13a5eeaf0184382c55a160cf2e89ed7afb2949f025a54f1e88f9e3fc
 DIST exim-4.96-gentoo-patches-r0.tar.xz 13308 BLAKE2B 
e01cd8b90593329d858cced27bea9da4860e80500c0b0b3f86418931a77616ac1e4a532cfffc551de5844bfcbcd115c1591b28577c234beb551458dc0877e764
 SHA512 
0a8d7b5903c8cd7c2cc07e4ea3ed62200ee0116fe0b5513ec97ba7f3ab1dd5cd0dc181eb93c3c1c7f767be7df3546ac07b622a8f4352eb883323c3a005a1c7db
 DIST exim-4.96.2.tar.xz 1879896 BLAKE2B 
f172340e5f896dc1996e4e3cf46515c2336c47d3390524ca91cb9ef7258a62b83426592de582aa792584cbeaace519b4edea5e62b3ebeb8e5f599379255e04a5
 SHA512 
dc9f6a114e64ac826489edff88d50a24195b64714428e691c10a7bfb119b3ebb6455bf80cbb34dfd0a4e2e44cbde72effb009357a8e0a6065e512fe32092e3ed
 DIST exim-4.96.tar.xz 1879152 BLAKE2B 
4b424f2ebc661bd0db35d7f6da86300c6d5cb5b9a52cddd24fdd452daa76c84e471d4f8f278cf951d1503b01fd46fc3e6858d6feded09f34253d2cf2ae99b45a
 SHA512 
6b863661465a0b9897c1b71875c5196a1903cf560dd85de45b08242b9731edb2bc10eb56945d62e477e5d15cc7a8d493915bff2ca81689673a8091c66f62c89e
 DIST exim-4.97.tar.xz 1909536 BLAKE2B 
b0f09d5f162853996976c222786de14e2104acdf01fd61da486f59f4cf8af1182cdfb7ea31fd55ccfd9c57256e7f442dc1b46727e08fe2eca82a296ac4ae7899
 SHA512 
b28cbb49fa7e143dfcc94e004d57cf98a1945013e676cd103c1ee4cf52933d49d378baa13bea2663353dba97745d6b2ab8b7b66cde870788a2d85d7abd716968
-DIST exim-pdf-4.94.2.tar.xz 2092248 BLAKE2B 
973ab4f117fdb58afa017bc41b4496fac1277e707a9926d67317c455b0bd617021c17cba6c8d793d8962aacef12c0790d5add7174017512b7b1ea070f8e8533d
 SHA512 
3a661f69d81a992798d4b7e5b7def7cfffa297a7b3c02a6631be426cefff5a6e8783fa322a1bd105d01f7b06968d01e77963e6ab7be3157f63eb62eb6ff172b0
 DIST exim-pdf-4.96.2.tar.xz 2132268 BLAKE2B 
9104d42d742e7152d166b6158a6f060d0a29143b11e5064ecda177ead59ac66a9bb6ab3575e5bcaf7af5b49964d29b841285e67184592a8b64bab6099f4c8ac9
 SHA512 
c35eea4ab5510bba50d22813b28c9d2f5e4e2fed76993693b997f2090024dde674d58dffe044cb64642bf57b83fcae3bfc3dbcae43288fae11692ee49374df74
 DIST exim-pdf-4.96.tar.xz 2137468 BLAKE2B 
7f61767f91864c43a3b7b6ca36ec7f41da6ad7029687a38cfa9307c444c2ffbd3eb61d45645ffd20ec16ba64a37e1ff08c02e7e4e36499c7783679af9a399081
 SHA512 
05e94579631656330d95d237c58bc9fd52229a067c5846e7c3409b4c83040c9216819bcb0090673d9991fd59e2c2025340592b31b241b557c6775782106854d1
 DIST exim-pdf-4.97.tar.xz 2136852 BLAKE2B 
df188e658e9e86d1b651d12b29e8a440677d75cc0384bab829323582a3a89b62f34e504b759ef2824b7735056696aed6ac33a4ca10a74fc5bc036f150caaac12
 SHA512 
defd1e7d823f4eadd2afe426d9105a395421824a1b1941b97bfda408905bdd105b5c219b713e15506d25d98fa48e965228f8daab286dc1be14a387f567c0b58b

diff --git a/mail-mta/exim/exim-4.97-r1.ebuild 
b/mail-mta/exim/exim-4.96-r5.ebuild
similarity index 90%
copy from mail-mta/exim/exim-4.97-r1.ebuild
copy to mail-mta/exim/exim-4.96-r5.ebuild
index 3dbed307e7e4..95cd963bee1d 100644
--- a/mail-mta/exim/exim-4.97-r1.ebuild
+++ b/mail-mta/exim/exim-4.96-r5.ebuild
@@ -3,7 +3,7 @@
 
 EAPI="7"
 
-inherit db-use flag-o-matic toolchain-funcs pam systemd
+inherit db-use toolchain-funcs pam systemd
 
 IUSE="arc berkdb +dane dcc +dkim dlfunc dmarc +dnsdb doc dovecot-sasl
 dsn gdbm gnutls idn ipv6 ldap lmtp maildir mbx
@@ -35,6 +35,7 @@ COMM_URI="https://downloads.exim.org/exim4${SDIR}";
 GPV="r0"
 DESCRIPTION="A highly configurable, drop-in replacement for sendmail"
 SRC_URI="${COMM_URI}/${P//_rc/-RC}.tar.xz
+       
https://dev.gentoo.org/~grobian/distfiles/${P}-gentoo-patches-${GPV}.tar.xz
        mirror://gentoo/system_filter.exim.gz
        doc? ( ${COMM_URI}/${PN}-pdf-${PV//_rc/-RC}.tar.xz )"
 HOMEPAGE="https://www.exim.org/";
@@ -111,11 +112,29 @@ src_prepare() {
        # Legacy patches which need a respin for -p1
        eapply -p0 "${FILESDIR}"/exim-4.14-tail.patch
        eapply -p0 "${FILESDIR}"/exim-4.74-radius-db-ENV-clash.patch # 287426
-       eapply     "${FILESDIR}"/exim-4.97-as-needed-ldflags.patch # 352265, 
391279
+       eapply     "${FILESDIR}"/exim-4.93-as-needed-ldflags.patch # 352265, 
391279
        eapply -p0 "${FILESDIR}"/exim-4.76-crosscompile.patch # 266591
        eapply     "${FILESDIR}"/exim-4.69-r1.27021.patch
-       eapply     "${FILESDIR}"/exim-4.97-localscan_dlopen.patch
-       eapply     "${FILESDIR}"/exim-4.97-no-exim_id_update.patch
+       eapply     "${FILESDIR}"/exim-4.95-localscan_dlopen.patch
+
+       # Upstream post-release fixes :(
+       local GPVDIR=${WORKDIR}/${P}-gentoo-patches-${GPV}
+       eapply     "${GPVDIR}"/exim-4.96-rewrite-malformed-addr-fix.patch # 
upstr
+       eapply     "${GPVDIR}"/exim-4.96-spf-memory-error-fix.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-regex-use-after-free.patch # upstr
+       eapply -p2 "${GPVDIR}"/exim-4.96-dmarc_use_after_free.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-deamon-startup-fix.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-openssl-verify-ocsp.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-openssl-double-expansion.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-recursion-dns_again.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-openssl-tls_eccurve-setting.patch # 
upstr
+       eapply     "${GPVDIR}"/exim-4.96-openssl-tls_eccurve-lt-3.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-openssl-bad-alpn.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-dane-dns_again.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-expansion-crash.patch # upstr
+       eapply     "${GPVDIR}"/exim-4.96-transport-crash.patch # upstr
+
+       eapply -p2 "${FILESDIR}"/exim-4.97-CVE-2023-51766.patch # 3063
 
        # oddity, they disable berkdb as hack, and then throw an error when
        # berkdb isn't enabled
@@ -124,6 +143,11 @@ src_prepare() {
                -e 's/define DB void/define DONTMESS void/' \
                src/auths/call_radius.c || die
 
+       # API changed from 1.3 to 1.4, upstream doesn't think 1.4 should be
+       # used, but 1.3 has a CVE and Gentoo (like most downstreams) only
+       # has 1.4 available
+       eapply "${FILESDIR}"/exim-4.94-opendmarc-1.4.patch
+
        if use maildir ; then
                eapply "${FILESDIR}"/exim-4.94-maildir.patch
        else
@@ -153,7 +177,6 @@ src_configure() {
 
        if use elibc_musl; then
                sed -i -e 's/^LIBS = -lnsl/LIBS =/g' OS/Makefile-Linux || die
-               append-cflags -DNO_EXECINFO
        fi
 
        local conffile="${EPREFIX}/etc/exim/exim.conf"

diff --git a/mail-mta/exim/exim-4.97-r1.ebuild 
b/mail-mta/exim/exim-4.97-r2.ebuild
similarity index 99%
rename from mail-mta/exim/exim-4.97-r1.ebuild
rename to mail-mta/exim/exim-4.97-r2.ebuild
index 3dbed307e7e4..06ad474f9e9c 100644
--- a/mail-mta/exim/exim-4.97-r1.ebuild
+++ b/mail-mta/exim/exim-4.97-r2.ebuild
@@ -116,6 +116,7 @@ src_prepare() {
        eapply     "${FILESDIR}"/exim-4.69-r1.27021.patch
        eapply     "${FILESDIR}"/exim-4.97-localscan_dlopen.patch
        eapply     "${FILESDIR}"/exim-4.97-no-exim_id_update.patch
+       eapply -p2 "${FILESDIR}"/exim-4.97-CVE-2023-51766.patch # 3063
 
        # oddity, they disable berkdb as hack, and then throw an error when
        # berkdb isn't enabled

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
new file mode 100644
index 000000000000..7eed4eb1855f
--- /dev/null
+++ b/mail-mta/exim/files/exim-4.97-CVE-2023-51766.patch
@@ -0,0 +1,265 @@
+https://nvd.nist.gov/vuln/detail/CVE-2023-51766
+
+
+From cf1376206284f2a4f11e32d931d4aade34c206c5 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <[email protected]>
+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 <[email protected]>
+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";

Reply via email to