From: Timo Sirainen Date: Fri, 4 Jun 2021 09:46:53 +0000 (+0300) Subject: lib-imap: imap-parser - Parse literal size using as same algorithm as str_parse*(). X-Git-Tag: 2.3.16~59 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=70defb0fb706434733944019803565d07e6f7f6b;p=thirdparty%2Fdovecot%2Fcore.git lib-imap: imap-parser - Parse literal size using as same algorithm as str_parse*(). This prevents wrapping the integer value and fixes an ubsan complaint. Based on Stephan's similar patch in managesieve-parser. --- diff --git a/src/lib-imap/imap-parser.c b/src/lib-imap/imap-parser.c index 20cee08c29..2deb75f5fb 100644 --- a/src/lib-imap/imap-parser.c +++ b/src/lib-imap/imap-parser.c @@ -438,7 +438,7 @@ static bool imap_parser_read_literal(struct imap_parser *parser, const unsigned char *data, size_t data_size) { - size_t i, prev_size; + size_t i; /* expecting digits + "}" */ for (i = parser->cur_pos; i < data_size; i++) { @@ -465,15 +465,16 @@ static bool imap_parser_read_literal(struct imap_parser *parser, return FALSE; } - prev_size = parser->literal_size; - parser->literal_size = parser->literal_size*10 + (data[i]-'0'); - - if (parser->literal_size < prev_size) { - /* wrapped around, abort. */ - parser->error = IMAP_PARSE_ERROR_LITERAL_TOO_BIG; - parser->error_msg = "Literal size too large"; - return FALSE; + if (parser->literal_size >= ((uoff_t)-1 / 10)) { + if (parser->literal_size > ((uoff_t)-1 / 10) || + (uoff_t)(data[i] - '0') > ((uoff_t)-1 % 10)) { + parser->error = IMAP_PARSE_ERROR_LITERAL_TOO_BIG; + parser->error_msg = "Literal size too large"; + return FALSE; + } } + parser->literal_size = parser->literal_size * 10 + + (data[i] - '0'); } parser->cur_pos = i;