From: Timo Sirainen Date: Mon, 27 Jan 2020 20:52:51 +0000 (+0200) Subject: lib-index: Fix potential assert-crash when refreshing index without any views X-Git-Tag: 2.3.10~113 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a26da45b57f5ce948dbe72828f16d2e3b4566593;p=thirdparty%2Fdovecot%2Fcore.git lib-index: Fix potential assert-crash when refreshing index without any views This is similar to the previous fix. If there are no references to the log file head, refreshing the index will result in assert-crash. This seems to have happened in some very rare situations. Mainly found it via the unit test though. Fixes: Panic: file mail-transaction-log.c: line 25 (mail_transaction_log_set_head): assertion failed: (log->files != NULL) --- diff --git a/src/lib-index/mail-transaction-log.c b/src/lib-index/mail-transaction-log.c index 5a9cee1623..1133a83bb0 100644 --- a/src/lib-index/mail-transaction-log.c +++ b/src/lib-index/mail-transaction-log.c @@ -368,9 +368,10 @@ mail_transaction_log_refresh(struct mail_transaction_log *log, bool nfs_flush, i_assert(!file->locked); - if (--log->head->refcount == 0) - mail_transaction_logs_clean(log); + struct mail_transaction_log_file *old_head = log->head; mail_transaction_log_set_head(log, file); + if (--old_head->refcount == 0) + mail_transaction_logs_clean(log); *reason_r = "Log reopened"; return 0; } diff --git a/src/lib-index/test-mail-index.c b/src/lib-index/test-mail-index.c index c18f42b5f7..f54ea39ec9 100644 --- a/src/lib-index/test-mail-index.c +++ b/src/lib-index/test-mail-index.c @@ -8,12 +8,15 @@ static void test_mail_index_rotate(void) { - struct mail_index *index; + struct mail_index *index, *index2; struct mail_index_view *view; struct mail_index_transaction *trans; + struct mail_transaction_log_file *file; + const char *reason; test_begin("mail index rotate"); index = test_mail_index_init(); + index2 = test_mail_index_open(); view = mail_index_view_open(index); /* First rotation of the index. The view will point to the old index. */ @@ -27,8 +30,13 @@ static void test_mail_index_rotate(void) mail_index_reset(trans); test_assert(mail_index_transaction_commit(&trans) == 0); + /* The 2nd index's log head also doesn't have any extra references. + Check that it doesn't crash. */ + test_assert(mail_transaction_log_find_file(index2->log, 3, FALSE, &file, &reason) == 0); + mail_index_view_close(&view); test_mail_index_deinit(&index); + test_mail_index_deinit(&index2); test_end(); }