More checks on header line length during reception
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 10 Jan 2019 21:15:11 +0000 (21:15 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 23 Jan 2019 12:08:53 +0000 (12:08 +0000)
(cherry picked from commit 56ac062a3ff94fc4e1bbfc2293119c079a4e980b)

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

index 05ad0c213305e993b1c662ca6a3560ef2bc55a87..79e7fa1735df04c39944b0be11c876122be3e88a 100644 (file)
@@ -71,13 +71,17 @@ JH/33 Bug 2338: Fix the cyrus-sasl authenticator to fill in the
       $authenticated_fail_id variable on authentication failure.  Previously
       it was unset.
 
       $authenticated_fail_id variable on authentication failure.  Previously
       it was unset.
 
-JH/36 Harder the handling of string-lists.  When a list consisted of a sole
+JH/36 Harden the handling of string-lists.  When a list consisted of a sole
       "<" character, which should be a list-separator specification, we walked
       off past the nul-terimation.
 
 AM/01 GnuTLS: repeat lowlevel read and write operations while they return error
       codes indicating retry.  Under TLS1.3 this becomes required.
 
       "<" character, which should be a list-separator specification, we walked
       off past the nul-terimation.
 
 AM/01 GnuTLS: repeat lowlevel read and write operations while they return error
       codes indicating retry.  Under TLS1.3 this becomes required.
 
+JH/41 Fix the loop reading a message header line to check for integer overflow,
+      and more-often against header_maxsize.  Previously a crafted message could
+      induce a crash of the recive process; now the message is cleanly rejected.
+
 
 Exim version 4.91
 -----------------
 
 Exim version 4.91
 -----------------
index f6db46c424f523798c3e68473d6e4f46379aa163..e139e0d547b196c4853719c11f206dd26fd926b2 100644 (file)
@@ -1813,8 +1813,11 @@ for (;;)
   if (ptr >= header_size - 4)
     {
     int oldsize = header_size;
   if (ptr >= header_size - 4)
     {
     int oldsize = header_size;
-    /* header_size += 256; */
+
+    if (header_size >= INT_MAX/2)
+      goto OVERSIZE;
     header_size *= 2;
     header_size *= 2;
+
     if (!store_extend(next->text, oldsize, header_size))
       next->text = store_newblock(next->text, header_size, ptr);
     }
     if (!store_extend(next->text, oldsize, header_size))
       next->text = store_newblock(next->text, header_size, ptr);
     }
@@ -1920,6 +1923,7 @@ for (;;)
 
   if (message_size >= header_maxsize)
     {
 
   if (message_size >= header_maxsize)
     {
+OVERSIZE:
     next->text[ptr] = 0;
     next->slen = ptr;
     next->type = htype_other;
     next->text[ptr] = 0;
     next->slen = ptr;
     next->type = htype_other;
@@ -1991,7 +1995,8 @@ for (;;)
     if (nextch == ' ' || nextch == '\t')
       {
       next->text[ptr++] = nextch;
     if (nextch == ' ' || nextch == '\t')
       {
       next->text[ptr++] = nextch;
-      message_size++;
+      if (++message_size >= header_maxsize)
+       goto OVERSIZE;
       continue;                      /* Iterate the loop */
       }
     else if (nextch != EOF) (receive_ungetc)(nextch);   /* For next time */
       continue;                      /* Iterate the loop */
       }
     else if (nextch != EOF) (receive_ungetc)(nextch);   /* For next time */