Mercurial > dovecot > original-hg > dovecot-1.2
changeset 2917:e657c7874962 HEAD
Crashfixes for reading corrupted cache files.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 29 Nov 2004 14:30:27 +0200 |
parents | d1780331ad04 |
children | 7039fc53b4c8 |
files | src/lib-index/mail-cache-lookup.c src/lib-index/mail-cache-private.h src/lib-index/mail-cache-transaction.c |
diffstat | 3 files changed, 24 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-cache-lookup.c Mon Nov 29 14:21:24 2004 +0200 +++ b/src/lib-index/mail-cache-lookup.c Mon Nov 29 14:30:27 2004 +0200 @@ -9,40 +9,43 @@ #define CACHE_PREFETCH 1024 -const struct mail_cache_record * -mail_cache_get_record(struct mail_cache *cache, uint32_t offset) +int mail_cache_get_record(struct mail_cache *cache, uint32_t offset, + const struct mail_cache_record **rec_r) { const struct mail_cache_record *cache_rec; + *rec_r = NULL; if (offset == 0) - return NULL; + return 0; if (mail_cache_map(cache, offset, sizeof(*cache_rec) + CACHE_PREFETCH) < 0) - return NULL; + return -1; if (offset + sizeof(*cache_rec) > cache->mmap_length) { mail_cache_set_corrupted(cache, "record points outside file"); - return NULL; + return -1; } cache_rec = CACHE_RECORD(cache, offset); if (cache_rec->size < sizeof(*cache_rec)) { mail_cache_set_corrupted(cache, "invalid record size"); - return NULL; + return -1; } if (cache_rec->size > CACHE_PREFETCH) { if (mail_cache_map(cache, offset, cache_rec->size) < 0) - return NULL; + return -1; cache_rec = CACHE_RECORD(cache, offset); } if (cache_rec->size > cache->mmap_length || offset + cache_rec->size > cache->mmap_length) { mail_cache_set_corrupted(cache, "record points outside file"); - return NULL; + return -1; } - return cache_rec; + + *rec_r = cache_rec; + return 0; } static int @@ -94,7 +97,8 @@ unsigned int field; int ret; - cache_rec = mail_cache_get_record(view->cache, *offset); + if (mail_cache_get_record(view->cache, *offset, &cache_rec) < 0) + return -1; if (cache_rec == NULL) { *offset = 0; return 1; @@ -126,7 +130,9 @@ /* field reading might have re-mmaped the file and caused cache_rec to break. need to get it again. */ - cache_rec = mail_cache_get_record(view->cache, *offset); + if (mail_cache_get_record(view->cache, *offset, + &cache_rec) < 0) + return -1; i_assert(cache_rec != NULL); }
--- a/src/lib-index/mail-cache-private.h Mon Nov 29 14:21:24 2004 +0200 +++ b/src/lib-index/mail-cache-private.h Mon Nov 29 14:30:27 2004 +0200 @@ -178,8 +178,8 @@ int mail_cache_header_fields_get_next_offset(struct mail_cache *cache, uint32_t *offset_r); -const struct mail_cache_record * -mail_cache_get_record(struct mail_cache *cache, uint32_t offset); +int mail_cache_get_record(struct mail_cache *cache, uint32_t offset, + const struct mail_cache_record **rec_r); int mail_cache_foreach(struct mail_cache_view *view, uint32_t seq, mail_cache_foreach_callback_t *callback, void *context);
--- a/src/lib-index/mail-cache-transaction.c Mon Nov 29 14:21:24 2004 +0200 +++ b/src/lib-index/mail-cache-transaction.c Mon Nov 29 14:30:27 2004 +0200 @@ -768,7 +768,8 @@ i_assert(cache->locked); - cache_rec = mail_cache_get_record(cache, offset); + if (mail_cache_get_record(cache, offset, &cache_rec) < 0) + return -1; if (cache_rec == NULL) return 0; @@ -779,8 +780,9 @@ expunged. */ do { cache->hdr_copy.deleted_space += cache_rec->size; - cache_rec = - mail_cache_get_record(cache, cache_rec->prev_offset); + if (mail_cache_get_record(cache, cache_rec->prev_offset, + &cache_rec) < 0) + return -1; } while (cache_rec != NULL); cache->hdr_modified = TRUE;