Chunking: do not treat the first lonely dot special. CVE-2017-16944, Bug 2201
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Mon, 27 Nov 2017 21:42:33 +0000 (22:42 +0100)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Tue, 28 Nov 2017 21:40:59 +0000 (22:40 +0100)
(cherry picked from commit 178ecb70987f024f0e775d87c2f8b2cf587dd542)

Change log update

(cherry picked from commit b488395f4d99d44a950073a64b35ec8729102782)

doc/doc-txt/ChangeLog
src/src/receive.c
src/src/smtp_in.c

index a2d9339c13daeeb41a5f25162e4da03cea9958bc..541ebaf544b8998cd59712d0b5135d9032969429 100644 (file)
@@ -61,7 +61,11 @@ JH/30 Fix a logging bug on aarch64: an unsafe routine was previously used for
 
 JH/34 Bug 2199: fix a use-after-free while reading smtp input for header lines.
       A crafted sequence of BDAT commands could result in in-use memory beeing
-      freed.
+      freed.  CVE-2017-16943.
+
+HS/03 Bug 2201: Fix checking for leading-dot on a line during headers reading
+      from SMTP input.  Previously it was always done; now only done for DATA
+      and not BDAT commands.  CVE-2017-16944.
 
 
 Exim version 4.89
index 20672dbe91eea44d974ba39049ff383f118369d6..2812ea2c87743f5db2171cbf86e00c6c24d08a9e 100644 (file)
@@ -1827,7 +1827,7 @@ for (;;)
   prevent further reading), and break out of the loop, having freed the
   empty header, and set next = NULL to indicate no data line. */
 
-  if (ptr == 0 && ch == '.' && (smtp_input || dot_ends))
+  if (ptr == 0 && ch == '.' && dot_ends)
     {
     ch = (receive_getc)(GETC_BUFFER_UNLIMITED);
     if (ch == '\r')
index 1b45f84d9c8244d76f0d42dd12b77c834c86ff67..02075404dc8eb05ab25fdafd9d1ff0280bd07279 100644 (file)
@@ -4955,16 +4955,23 @@ while (done <= 0)
       DEBUG(D_receive) debug_printf("chunking state %d, %d bytes\n",
                                    (int)chunking_state, chunking_data_left);
 
+      /* push the current receive_* function on the "stack", and
+      replace them by bdat_getc(), which in turn will use the lwr_receive_*
+      functions to do the dirty work. */
       lwr_receive_getc = receive_getc;
       lwr_receive_ungetc = receive_ungetc;
+
       receive_getc = bdat_getc;
       receive_ungetc = bdat_ungetc;
 
+      dot_ends = FALSE;
+
       goto DATA_BDAT;
       }
 
     case DATA_CMD:
     HAD(SCH_DATA);
+    dot_ends = TRUE;
 
     DATA_BDAT:         /* Common code for DATA and BDAT */
     if (!discarded && recipients_count <= 0)