]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Detect corrupted mail size when calculating body size
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 22 Oct 2020 19:49:56 +0000 (22:49 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 15 Jan 2021 08:23:36 +0000 (08:23 +0000)
When body size is calculated from message size - header size, make sure that
the message size is at least as large as the header size. Otherwise treat
the message size as corrupted.

src/lib-storage/index/index-mail.c

index 62dd4e03b256c718fb655a0d5c3b53cae89c4aa7..b520cc7af917a003d94d7df5b0650f83f4db7272 100644 (file)
@@ -508,11 +508,25 @@ static void index_mail_try_set_body_size(struct index_mail *mail)
                   However, don't do this if there's a possibility that
                   physical_size or virtual_size don't actually match the
                   mail stream's size (e.g. buggy imapc servers). */
-               data->body_size.physical_size = data->physical_size -
-                       data->hdr_size.physical_size;
-               data->body_size.virtual_size = data->virtual_size -
-                       data->hdr_size.virtual_size;
-               data->body_size_set = TRUE;
+               if (data->physical_size < data->hdr_size.physical_size) {
+                       mail_set_cache_corrupted(&mail->mail.mail,
+                               MAIL_FETCH_PHYSICAL_SIZE, t_strdup_printf(
+                               "Cached physical size smaller than header size "
+                               "(%"PRIuUOFF_T" < %"PRIuUOFF_T")",
+                               data->physical_size, data->hdr_size.physical_size));
+               } else if (data->virtual_size < data->hdr_size.virtual_size) {
+                       mail_set_cache_corrupted(&mail->mail.mail,
+                               MAIL_FETCH_VIRTUAL_SIZE, t_strdup_printf(
+                               "Cached virtual size smaller than header size "
+                               "(%"PRIuUOFF_T" < %"PRIuUOFF_T")",
+                               data->virtual_size, data->hdr_size.virtual_size));
+               } else {
+                       data->body_size.physical_size = data->physical_size -
+                               data->hdr_size.physical_size;
+                       data->body_size.virtual_size = data->virtual_size -
+                               data->hdr_size.virtual_size;
+                       data->body_size_set = TRUE;
+               }
        }
 }