SECURITY: Don't miss the very last byte when reading long lines from -H
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Sat, 21 Nov 2020 21:18:56 +0000 (22:18 +0100)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Thu, 27 May 2021 19:30:35 +0000 (21:30 +0200)
Credits: Qualys

    2/ In src/spool_in.c:

     462   while (  (len = Ustrlen(big_buffer)) == big_buffer_size-1
     463         && big_buffer[len-1] != '\n'
     464         )
     465     {   /* buffer not big enough for line; certs make this possible */
     466     uschar * buf;
     467     if (big_buffer_size >= BIG_BUFFER_SIZE*4) goto SPOOL_READ_ERROR;
     468     buf = store_get_perm(big_buffer_size *= 2, FALSE);
     469     memcpy(buf, big_buffer, --len);

    The --len in memcpy() chops off a useful byte (we know for sure that
    big_buffer[len-1] is not a '\n' because we entered the while loop).

(cherry picked from commit 58454ea01c2e817481770954edf09ad82f3cd417)
(cherry picked from commit 2d9f1837bdd6c5946cb9cd997544eefc8cc14fc4)

src/src/spool_in.c

index f64c52c5a57ad411b2fed5cff1771a3ad8081ba3..09fe9c5f729bb4b3b76e121920c0d57fec89fe04 100644 (file)
@@ -468,7 +468,7 @@ for (;;)
     uschar * buf;
     if (big_buffer_size >= BIG_BUFFER_SIZE*4) goto SPOOL_READ_ERROR;
     buf = store_get_perm(big_buffer_size *= 2, FALSE);
     uschar * buf;
     if (big_buffer_size >= BIG_BUFFER_SIZE*4) goto SPOOL_READ_ERROR;
     buf = store_get_perm(big_buffer_size *= 2, FALSE);
-    memcpy(buf, big_buffer, --len);
+    memcpy(buf, big_buffer, len);
     big_buffer = buf;
     if (Ufgets(big_buffer+len, big_buffer_size-len, fp) == NULL)
       goto SPOOL_READ_ERROR;
     big_buffer = buf;
     if (Ufgets(big_buffer+len, big_buffer_size-len, fp) == NULL)
       goto SPOOL_READ_ERROR;