There is finally a fix for this bug, from the author.
These are the changesets fixing it:
changeset: 18534:94bd895721d8
user: Timo Sirainen <t...@iki.fi>
date: Thu May 07 00:01:08 2015 +0300
summary: mbox: Fixed crash/corruption in some situations when the first
mail was expunged.
changeset: 18679:b6ea460e7cc4
user: Timo Sirainen <t...@iki.fi>
date: Wed May 13 19:24:55 2015 +0300
summary: mbox: Fixed corruption in some usage patterns.
which you will find attached.
Please consider an upload for stable fixing this.
Thanks.
From: Timo Sirainen <t...@iki.fi>
Subject: mbox: Fixed crash/corruption in some situations when the first mail was expunged.
--- a/src/lib-storage/index/mbox/mbox-sync.c
+++ b/src/lib-storage/index/mbox/mbox-sync.c
@@ -630,7 +630,7 @@
static int mbox_sync_handle_header(struct mbox_sync_mail_context *mail_ctx)
{
struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
- uoff_t orig_from_offset;
+ uoff_t orig_from_offset, postlf_from_offset = (uoff_t)-1;
off_t move_diff;
int ret;
@@ -647,6 +647,7 @@
if (sync_ctx->first_mail_crlf_expunged)
mail_ctx->mail.from_offset++;
}
+ postlf_from_offset = mail_ctx->mail.from_offset;
/* read the From-line before rewriting overwrites it */
if (mbox_read_from_line(mail_ctx) < 0)
@@ -700,10 +701,16 @@
/* create dummy message to describe the expunged data */
struct mbox_sync_mail mail;
+ /* if this is going to be the first mail, increase the
+ from_offset to point to the beginning of the
+ From-line, because the previous [CR]LF is already
+ covered by expunged_space. */
+ i_assert(postlf_from_offset != (uoff_t)-1);
+ mail_ctx->mail.from_offset = postlf_from_offset;
+
memset(&mail, 0, sizeof(mail));
mail.expunged = TRUE;
mail.offset = mail.from_offset =
- (sync_ctx->dest_first_mail ? 1 : 0) +
mail_ctx->mail.from_offset -
sync_ctx->expunged_space;
mail.space = sync_ctx->expunged_space;
From: Timo Sirainen <t...@iki.fi>
Subject: mbox: Fixed corruption in some usage patterns.
--- a/src/lib-storage/index/mbox/mbox-sync.c
+++ b/src/lib-storage/index/mbox/mbox-sync.c
@@ -679,8 +679,10 @@
}
} else if (mail_ctx->need_rewrite) {
mbox_sync_update_header(mail_ctx);
- if (sync_ctx->delay_writes) {
- /* mark it dirty and do it later */
+ if (sync_ctx->delay_writes && sync_ctx->need_space_seq == 0) {
+ /* mark it dirty and do it later. we can't do this
+ if we're in the middle of rewriting acquiring more
+ space. */
mail_ctx->dirty = TRUE;
return 0;
}