dovecot-1.2: Fixed crashes related to struct mail_index_map_mods...

dovecot at dovecot.org dovecot at dovecot.org
Sun Aug 31 11:02:18 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/32a045eaf6b6
changeset: 8131:32a045eaf6b6
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Aug 31 11:02:13 2008 +0300
description:
Fixed crashes related to struct mail_index_map_modseq handling.

diffstat:

5 files changed, 51 insertions(+), 10 deletions(-)
src/lib-index/mail-index-map.c         |   19 +++++++++++++++----
src/lib-index/mail-index-modseq.c      |   29 ++++++++++++++++++++++++++---
src/lib-index/mail-index-modseq.h      |    5 ++++-
src/lib-index/mail-index-sync-update.c |    4 ++++
src/lib-index/mail-index-view-sync.c   |    4 ++--

diffs (172 lines):

diff -r b97c3be33b04 -r 32a045eaf6b6 src/lib-index/mail-index-map.c
--- a/src/lib-index/mail-index-map.c	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-map.c	Sun Aug 31 11:02:13 2008 +0300
@@ -978,7 +978,7 @@ static void mail_index_record_map_free(s
 	}
 	array_free(&rec_map->maps);
 	if (rec_map->modseq != NULL)
-		mail_index_map_modseq_free(rec_map->modseq);
+		mail_index_map_modseq_free(&rec_map->modseq);
 	i_free(rec_map);
 }
 
@@ -991,8 +991,10 @@ static void mail_index_record_map_unlink
 	for (i = 0; i < count; i++) {
 		if (maps[i] == map) {
 			array_delete(&map->rec_map->maps, i, 1);
-			if (i == 0 && count == 1)
+			if (i == 0 && count == 1) {
 				mail_index_record_map_free(map, map->rec_map);
+				map->rec_map = NULL;
+			}
 			return;
 		}
 	}
@@ -1145,6 +1147,10 @@ void mail_index_record_map_move_to_priva
 	} else {
 		new_map = map->rec_map;
 	}
+	if (map->rec_map->modseq != NULL) {
+		new_map->modseq =
+			mail_index_map_modseq_clone(map->rec_map->modseq);
+	}
 
 	if (new_map->records_count != map->hdr.messages_count) {
 		new_map->records_count = map->hdr.messages_count;
@@ -1168,8 +1174,13 @@ void mail_index_map_move_to_memory(struc
 
 	i_assert(map->rec_map->lock_id != 0);
 
-	new_map = array_count(&map->rec_map->maps) == 1 ? map->rec_map :
-		mail_index_record_map_alloc(map);
+	if (array_count(&map->rec_map->maps) == 1)
+		new_map = map->rec_map;
+	else {
+		new_map = mail_index_record_map_alloc(map);
+		new_map->modseq = map->rec_map->modseq == NULL ? NULL :
+			mail_index_map_modseq_clone(map->rec_map->modseq);
+	}
 
 	mail_index_map_copy_records(new_map, map->rec_map,
 				    map->hdr.record_size);
diff -r b97c3be33b04 -r 32a045eaf6b6 src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-modseq.c	Sun Aug 31 11:02:13 2008 +0300
@@ -494,9 +494,16 @@ void mail_index_modseq_sync_end(struct m
 	struct mail_index_modseq_sync *ctx = *_ctx;
 
 	*_ctx = NULL;
-	if (ctx->mmap != NULL)
+	if (ctx->mmap != NULL) {
+		i_assert(ctx->mmap == ctx->view->map->rec_map->modseq);
 		mail_index_modseq_update_header(ctx);
+	}
 	i_free(ctx);
+}
+
+void mail_index_modseq_sync_map_replaced(struct mail_index_modseq_sync *ctx)
+{
+	ctx->mmap = mail_index_map_modseq(ctx->view);
 }
 
 void mail_index_modseq_hdr_update(struct mail_index_modseq_sync *ctx)
@@ -601,10 +608,26 @@ void mail_index_modseq_reset_keywords(st
 		modseqs_idx_update(ctx, i, seq1, seq2);
 }
 
-void mail_index_map_modseq_free(struct mail_index_map_modseq *mmap)
-{
+struct mail_index_map_modseq *
+mail_index_map_modseq_clone(const struct mail_index_map_modseq *mmap)
+{
+	struct mail_index_map_modseq *new_mmap;
+
+	new_mmap = i_new(struct mail_index_map_modseq, 1);
+	i_array_init(&new_mmap->metadata_modseqs,
+		     array_count(&mmap->metadata_modseqs) + 16);
+	array_append_array(&new_mmap->metadata_modseqs,
+			   &mmap->metadata_modseqs);
+	return new_mmap;
+}
+
+void mail_index_map_modseq_free(struct mail_index_map_modseq **_mmap)
+{
+	struct mail_index_map_modseq *mmap = *_mmap;
 	struct metadata_modseqs *metadata;
 	unsigned int i, count;
+
+	*_mmap = NULL;
 
 	metadata = array_get_modifiable(&mmap->metadata_modseqs, &count);
 	for (i = 0; i < count; i++) {
diff -r b97c3be33b04 -r 32a045eaf6b6 src/lib-index/mail-index-modseq.h
--- a/src/lib-index/mail-index-modseq.h	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-modseq.h	Sun Aug 31 11:02:13 2008 +0300
@@ -40,6 +40,7 @@ mail_index_modseq_sync_begin(struct mail
 mail_index_modseq_sync_begin(struct mail_index_sync_map_ctx *sync_map_ctx);
 void mail_index_modseq_sync_end(struct mail_index_modseq_sync **ctx);
 
+void mail_index_modseq_sync_map_replaced(struct mail_index_modseq_sync *ctx);
 void mail_index_modseq_hdr_update(struct mail_index_modseq_sync *ctx);
 void mail_index_modseq_append(struct mail_index_modseq_sync *ctx, uint32_t seq);
 void mail_index_modseq_expunge(struct mail_index_modseq_sync *ctx,
@@ -53,7 +54,9 @@ void mail_index_modseq_reset_keywords(st
 void mail_index_modseq_reset_keywords(struct mail_index_modseq_sync *ctx,
 				      uint32_t seq1, uint32_t seq2);
 
-void mail_index_map_modseq_free(struct mail_index_map_modseq *mmap);
+struct mail_index_map_modseq *
+mail_index_map_modseq_clone(const struct mail_index_map_modseq *mmap);
+void mail_index_map_modseq_free(struct mail_index_map_modseq **mmap);
 
 bool mail_index_modseq_get_next_log_offset(struct mail_index_view *view,
 					   uint64_t modseq, uint32_t *log_seq_r,
diff -r b97c3be33b04 -r 32a045eaf6b6 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-sync-update.c	Sun Aug 31 11:02:13 2008 +0300
@@ -65,6 +65,8 @@ static void mail_index_sync_replace_map(
 
 	if (ctx->type != MAIL_INDEX_SYNC_HANDLER_VIEW)
 		view->index->map = map;
+
+	mail_index_modseq_sync_map_replaced(ctx->modseq_ctx);
 }
 
 static void
@@ -82,6 +84,7 @@ mail_index_sync_move_to_private_memory(s
 
 	if (!MAIL_INDEX_MAP_IS_IN_MEMORY(ctx->view->map))
 		mail_index_map_move_to_memory(ctx->view->map);
+	mail_index_modseq_sync_map_replaced(ctx->modseq_ctx);
 }
 
 struct mail_index_map *
@@ -89,6 +92,7 @@ mail_index_sync_get_atomic_map(struct ma
 {
 	mail_index_sync_move_to_private_memory(ctx);
 	mail_index_record_map_move_to_private(ctx->view->map);
+	mail_index_modseq_sync_map_replaced(ctx->modseq_ctx);
 	ctx->view->map->write_atomic = TRUE;
 	return ctx->view->map;
 }
diff -r b97c3be33b04 -r 32a045eaf6b6 src/lib-index/mail-index-view-sync.c
--- a/src/lib-index/mail-index-view-sync.c	Sun Aug 31 10:22:10 2008 +0300
+++ b/src/lib-index/mail-index-view-sync.c	Sun Aug 31 11:02:13 2008 +0300
@@ -559,8 +559,6 @@ mail_index_view_sync_begin(struct mail_i
 		return ctx;
 	}
 
-	mail_index_sync_map_init(&ctx->sync_map_ctx, view,
-				 MAIL_INDEX_SYNC_HANDLER_VIEW);
 	if (ret == 0) {
 		ctx->log_was_lost = TRUE;
 		if (!sync_expunges)
@@ -629,6 +627,8 @@ mail_index_view_sync_begin(struct mail_i
 			ctx->sync_new_map->refcount++;
 		}
 	}
+	mail_index_sync_map_init(&ctx->sync_map_ctx, view,
+				 MAIL_INDEX_SYNC_HANDLER_VIEW);
 
 #ifdef DEBUG
 	mail_index_map_check(view->map);


More information about the dovecot-cvs mailing list