From: Jeremy Harris Date: Thu, 10 Jan 2019 21:15:11 +0000 (+0000) Subject: More checks on header line length during reception X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/9174338983e6872659fb29de4bc0b5b3a709185b More checks on header line length during reception (cherry picked from commit 56ac062a3ff94fc4e1bbfc2293119c079a4e980b) --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 05ad0c213..79e7fa173 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -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. -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. +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 ----------------- diff --git a/src/src/receive.c b/src/src/receive.c index f6db46c42..e139e0d54 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -1813,8 +1813,11 @@ for (;;) if (ptr >= header_size - 4) { int oldsize = header_size; - /* header_size += 256; */ + + if (header_size >= INT_MAX/2) + goto OVERSIZE; header_size *= 2; + 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) { +OVERSIZE: next->text[ptr] = 0; next->slen = ptr; next->type = htype_other; @@ -1991,7 +1995,8 @@ for (;;) 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 */