Mercurial > dovecot > original-hg > dovecot-1.2
changeset 48:5e9cf9565353 HEAD
More cleanups / potential overflow fixes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 27 Aug 2002 06:36:09 +0300 |
parents | 306c20092a96 |
children | 6be018ca51ef |
files | src/lib-index/mail-index-compress.c src/lib-index/mail-index-data.c src/lib-index/mail-index-data.h src/lib-index/mail-index-update-cache.c src/lib-index/mail-index.h |
diffstat | 5 files changed, 95 insertions(+), 67 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-compress.c Tue Aug 27 06:33:10 2002 +0300 +++ b/src/lib-index/mail-index-compress.c Tue Aug 27 06:36:09 2002 +0300 @@ -11,24 +11,29 @@ int mail_index_compress(MailIndex *index) { - MailIndexHeader *hdr; MailIndexRecord *rec, *hole_rec, *end_rec; - off_t fsize; + size_t fsize; if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) return FALSE; - hdr = index->get_header(index); - - if (hdr->first_hole_position == 0) { + if (index->header->first_hole_position == 0) { /* we don't need to compress after all. shouldn't happen.. */ index->header->flags &= ~MAIL_INDEX_FLAG_CACHE_FIELDS; return TRUE; } + if (index->header->first_hole_position >= (off_t)index->mmap_length) { + index_set_error(index, "Error in index file %s: " + "first_hole_position points outside file", + index->filepath); + index->header->flags |= MAIL_INDEX_FLAG_REBUILD; + return FALSE; + } + /* if we get interrupted, the whole index is probably corrupted. so keep rebuild-flag on while doing this */ - hdr->flags |= MAIL_INDEX_FLAG_REBUILD; + index->header->flags |= MAIL_INDEX_FLAG_REBUILD; if (!mail_index_fmsync(index, sizeof(MailIndexHeader))) return FALSE; @@ -36,8 +41,8 @@ end_rec = (MailIndexRecord *) ((char *) index->mmap_base + index->mmap_length); hole_rec = (MailIndexRecord *) ((char *) index->mmap_base + - hdr->first_hole_position); - rec = hole_rec + hdr->first_hole_records; + index->header->first_hole_position); + rec = hole_rec + index->header->first_hole_records; while (rec < end_rec) { if (rec->uid != 0) { memcpy(hole_rec, rec, sizeof(MailIndexRecord)); @@ -47,8 +52,8 @@ } /* truncate the file to get rid of the extra records */ - fsize = (char *) hole_rec - (char *) index->mmap_base; - if (ftruncate(index->fd, fsize) == -1) { + fsize = (size_t) ((char *) hole_rec - (char *) index->mmap_base); + if (ftruncate(index->fd, (off_t)fsize) == -1) { index_set_error(index, "ftruncate() failed for %s: %m", index->filepath); return FALSE; @@ -67,13 +72,61 @@ return TRUE; } -int mail_index_compress_data(MailIndex *index) +static int mail_index_copy_data(MailIndex *index, int fd, const char *path) { + MailIndexDataHeader data_hdr; MailIndexRecord *rec; - MailIndexDataHeader data_hdr; unsigned char *mmap_data; size_t mmap_data_size; off_t offset; + + mmap_data = mail_index_data_get_mmaped(index->data, &mmap_data_size); + if (mmap_data == NULL) + return FALSE; + + /* write data header */ + memset(&data_hdr, 0, sizeof(data_hdr)); + data_hdr.indexid = index->indexid; + if (write_full(fd, &data_hdr, sizeof(data_hdr)) < 0) { + index_set_error(index, "Error writing to temp index data " + "%s: %m", path); + return FALSE; + } + + /* no we'll begin the actual moving. keep rebuild-flag on + while doing it. */ + index->header->flags |= MAIL_INDEX_FLAG_REBUILD; + if (!mail_index_fmsync(index, sizeof(MailIndexHeader))) + return FALSE; + + offset = sizeof(data_hdr); + rec = index->lookup(index, 1); + while (rec != NULL) { + if (rec->data_position + rec->data_size > mmap_data_size) { + index_set_error(index, "Error in index file %s: " + "data_position+data_size points " + "outside file", index->filepath); + return FALSE; + } + + if (write_full(fd, mmap_data + rec->data_position, + rec->data_size) < 0) { + index_set_error(index, "Error writing to temp index " + "data %s: %m", path); + return FALSE; + } + + rec->data_position = offset; + offset += rec->data_size; + + rec = index->next(index, rec); + } + + return TRUE; +} + +int mail_index_compress_data(MailIndex *index) +{ const char *temppath, *datapath; int fd; @@ -83,52 +136,16 @@ if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) return FALSE; - mmap_data = mail_index_data_get_mmaped(index->data, &mmap_data_size); - if (mmap_data == NULL) - return FALSE; - fd = mail_index_create_temp_file(index, &temppath); if (fd == -1) return FALSE; - /* write data header */ - memset(&data_hdr, 0, sizeof(data_hdr)); - data_hdr.indexid = index->indexid; - if (write_full(fd, &data_hdr, sizeof(data_hdr)) < 0) { - index_set_error(index, "Error writing to temp index data " - "%s: %m", temppath); - (void)close(fd); - (void)unlink(temppath); - return FALSE; - } - - /* no we'll begin the actual moving. keep rebuild-flag on - while doing it. */ - index->header->flags |= MAIL_INDEX_FLAG_REBUILD; - if (!mail_index_fmsync(index, sizeof(MailIndexHeader))) { + if (!mail_index_copy_data(index, fd, temppath)) { (void)close(fd); (void)unlink(temppath); return FALSE; } - offset = sizeof(data_hdr); - rec = index->lookup(index, 1); - while (rec != NULL) { - if (write_full(fd, mmap_data + rec->data_position, - rec->data_size) < 0) { - index_set_error(index, "Error writing to temp index " - "data %s: %m", temppath); - (void)close(fd); - (void)unlink(temppath); - return FALSE; - } - - rec->data_position = offset; - offset += rec->data_size; - - rec = index->next(index, rec); - } - /* now, close the old data file and rename the temp file into new data file */ mail_index_data_free(index->data);
--- a/src/lib-index/mail-index-data.c Tue Aug 27 06:33:10 2002 +0300 +++ b/src/lib-index/mail-index-data.c Tue Aug 27 06:36:09 2002 +0300 @@ -70,8 +70,7 @@ /* doesn't exist, rebuild the index */ INDEX_MARK_CORRUPTED(index); } - index_set_error(index, "Can't open index data %s: %m", - path); + index_set_error(index, "Can't open index data %s: %m", path); return FALSE; } @@ -161,7 +160,7 @@ data->index->data = NULL; if (data->mmap_base != NULL) { - munmap(data->mmap_base, data->mmap_length); + (void)munmap(data->mmap_base, data->mmap_length); data->mmap_base = NULL; } @@ -204,7 +203,8 @@ data->dirty_mmap = TRUE; } -off_t mail_index_data_append(MailIndexData *data, void *buffer, size_t size) +off_t mail_index_data_append(MailIndexData *data, const void *buffer, + size_t size) { off_t pos; @@ -231,10 +231,11 @@ unsigned int data_size) { MailIndexDataHeader *hdr; - unsigned int max_del_space; + off_t max_del_space; i_assert(data->index->lock_type == MAIL_LOCK_EXCLUSIVE); + /* make sure the whole file is mmaped */ if (!mmap_update(data, 0, 0)) return FALSE; @@ -244,7 +245,7 @@ /* see if we've reached the max. deleted space in file */ if (data->mmap_length >= COMPRESS_MIN_SIZE) { max_del_space = data->mmap_length / 100 * COMPRESS_PERCENTAGE; - if (hdr->deleted_space >= (off_t)max_del_space) + if (hdr->deleted_space >= max_del_space) data->index->set_flags |= MAIL_INDEX_FLAG_COMPRESS_DATA; } return TRUE; @@ -274,7 +275,7 @@ MailField field) { MailIndexDataRecord *rec; - size_t pos, max_pos; + off_t pos, max_pos; if (index_rec->data_position == 0) { index_reset_error(data->index); @@ -285,7 +286,7 @@ return NULL; max_pos = index_rec->data_position + (off_t)index_rec->data_size; - if (max_pos > data->mmap_length) { + if (max_pos > (off_t)data->mmap_length) { INDEX_MARK_CORRUPTED(data->index); index_set_error(data->index, "Error in data file %s: " "Given data size larger than file size " @@ -297,9 +298,18 @@ pos = index_rec->data_position; do { - rec = (MailIndexDataRecord *) ((char *) data->mmap_base + pos); + if (pos + (off_t)sizeof(MailIndexDataRecord) > max_pos) { + INDEX_MARK_CORRUPTED(data->index); + index_set_error(data->index, "Error in data file %s: " + "Index points outside file " + "(%lu > %lu)", data->filepath, + (unsigned long) pos, + (unsigned long) data->mmap_length); + break; + } - if (pos + rec->full_field_size > max_pos) { + rec = (MailIndexDataRecord *) ((char *) data->mmap_base + pos); + if (pos + (off_t)DATA_RECORD_SIZE(rec) > max_pos) { INDEX_MARK_CORRUPTED(data->index); index_set_error(data->index, "Error in data file %s: " "Field size points outside file " @@ -330,13 +340,13 @@ mail_index_data_next(MailIndexData *data, MailIndexRecord *index_rec, MailIndexDataRecord *rec) { - size_t pos, max_pos; + off_t pos, max_pos; if (rec == NULL) return NULL; /* get position to next record */ - pos = DATA_FILE_POSITION(data, rec) + (off_t)DATA_RECORD_SIZE(rec); + pos = DATA_FILE_POSITION(data, rec) + DATA_RECORD_SIZE(rec); max_pos = index_rec->data_position + index_rec->data_size; /* make sure it's within range */ @@ -344,7 +354,7 @@ return NULL; rec = (MailIndexDataRecord *) ((char *) data->mmap_base + pos); - if (pos + rec->full_field_size > max_pos) { + if (pos + (off_t)DATA_RECORD_SIZE(rec) > max_pos) { INDEX_MARK_CORRUPTED(data->index); index_set_error(data->index, "Error in data file %s: " "Field size points outside file "
--- a/src/lib-index/mail-index-data.h Tue Aug 27 06:33:10 2002 +0300 +++ b/src/lib-index/mail-index-data.h Tue Aug 27 06:36:09 2002 +0300 @@ -16,7 +16,8 @@ /* Append new data at the end of the file. Returns the position in file where the data begins, or (off_t)-1 if error occured. */ -off_t mail_index_data_append(MailIndexData *data, void *buffer, size_t size); +off_t mail_index_data_append(MailIndexData *data, const void *buffer, + size_t size); /* Increase header->deleted_space field */ int mail_index_data_add_deleted_space(MailIndexData *data,
--- a/src/lib-index/mail-index-update-cache.c Tue Aug 27 06:33:10 2002 +0300 +++ b/src/lib-index/mail-index-update-cache.c Tue Aug 27 06:36:09 2002 +0300 @@ -28,7 +28,7 @@ if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) return FALSE; - cache_fields = index->get_header(index)->cache_fields; + cache_fields = index->header->cache_fields; rec = index->lookup(index, 1); while (rec != NULL) {
--- a/src/lib-index/mail-index.h Tue Aug 27 06:33:10 2002 +0300 +++ b/src/lib-index/mail-index.h Tue Aug 27 06:36:09 2002 +0300 @@ -117,9 +117,9 @@ unsigned int data_size; unsigned int cached_fields; - unsigned int header_size; - unsigned int body_size; - unsigned int full_virtual_size; + off_t header_size; + off_t body_size; + off_t full_virtual_size; }; #define MSG_HAS_VALID_CRLF_DATA(rec) \