From db3f056da3b16afa09bf807c717664689d35bdcb Mon Sep 17 00:00:00 2001 From: Georg Sauthoff Date: Fri, 8 Feb 2019 19:12:29 +0100 Subject: [PATCH 10/11] Fix fill_buf heap-buffer-overflow (#123) cf. https://sourceforge.net/p/bogofilter/bugs/123/ --- src/lexer.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/lexer.c b/src/lexer.c index 60692b6..b7b4b3b 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -11,6 +11,7 @@ #include #include +#include #include "base64.h" #include "bogoconfig.h" @@ -234,18 +235,16 @@ static int get_decoded_line(buff_t *buff) * no more bytes left to read, even though before the iconvert * call we had a positive number of bytes. This *will* lead to * a message truncation which we try to avoid by simply - * returning the original input buffer (which has positive - * length) instead. */ + * returning another in-band error code. */ if(buff->t.leng == 0) { - memcpy(buff, linebuff, sizeof(*buff)); - *linebuff = (const buff_t){0}; + count = -2; + } else { + /* + * iconvert, treating multi-byte sequences, can shrink or enlarge + * the output compared to its input. Correct count. + */ + count = buff->t.leng; } - - /* - * iconvert, treating multi-byte sequences, can shrink or enlarge - * the output compared to its input. Correct count. - */ - count = buff->t.leng; } #endif @@ -299,7 +298,9 @@ int buff_fill(buff_t *buff, size_t used, size_t need) while (size - leng > 2 && need > leng - used) { /* too few, read more */ int add = get_decoded_line(buff); + // get_decoded_line never returns EOF!?! if (add == EOF) return EOF; + if (add == -2) continue; if (add == 0) break ; cnt += add; leng += add; @@ -332,8 +333,8 @@ int yyinput(byte *buf, size_t used, size_t size) */ while ((cnt = get_decoded_line(&buff)) != 0) { - - count += cnt; + if (cnt > 0) + count += cnt; /* Note: some malformed messages can cause xfgetsl() to report ** "Invalid buffer size, exiting." and then abort. This @@ -365,6 +366,7 @@ int yyinput(byte *buf, size_t used, size_t size) if (msg_state && msg_state->mime_dont_decode && (msg_state->mime_disposition != MIME_DISPOSITION_UNKNOWN)) { + assert(count <= (int)size); return (count == EOF ? 0 : count); /* not decode at all */ } @@ -386,6 +388,7 @@ int yyinput(byte *buf, size_t used, size_t size) if (DEBUG_LEXER(2)) fprintf(dbgout, "*** yyinput(\"%-.*s\", %lu, %lu) = %d\n", count, buf, (unsigned long)used, (unsigned long)size, count); + assert(count <= (int)size); return (count == EOF ? 0 : count); } -- 2.20.1