# HG changeset patch # User Timo Sirainen # Date 1042326816 -7200 # Node ID f7d0209bb7a62d273b7e3d8b1b85e6f618c2538a # Parent 411006be3c66edfb0e548f5c92dac8251049bc9a Do some more sanity checking when updating cached message_part. If anything fails, log the error and set index corrupted. diff -r 411006be3c66 -r f7d0209bb7a6 src/lib-index/mbox/mbox-sync-full.c --- a/src/lib-index/mbox/mbox-sync-full.c Sat Jan 11 21:55:56 2003 +0200 +++ b/src/lib-index/mbox/mbox-sync-full.c Sun Jan 12 01:13:36 2003 +0200 @@ -48,6 +48,7 @@ struct message_size *hdr_size) { const void *part_data; + const char *error; void *part_data_copy; uoff_t virtual_size; size_t size; @@ -80,7 +81,10 @@ memcpy(part_data_copy, part_data, size); if (!message_part_serialize_update_header(part_data_copy, size, - hdr_size)) { + hdr_size, &error)) { + index_set_corrupted(index, + "Corrupted cached message_part data (%s)", + error); t_pop(); return FALSE; } diff -r 411006be3c66 -r f7d0209bb7a6 src/lib-mail/message-part-serialize.c --- a/src/lib-mail/message-part-serialize.c Sat Jan 11 21:55:56 2003 +0200 +++ b/src/lib-mail/message-part-serialize.c Sun Jan 12 01:13:36 2003 +0200 @@ -177,27 +177,34 @@ return TRUE; } +static int check_size(size_t size, const char **error) +{ + if (size < sizeof(struct serialized_message_part)) { + *error = "Not enough data for root"; + return FALSE; + } + + if ((size % sizeof(struct serialized_message_part)) != 0) { + *error = "Incorrect data size"; + return FALSE; + } + + if (size / sizeof(struct serialized_message_part) > UINT_MAX) { + *error = "Insane amount of data"; + return FALSE; + } + + return TRUE; +} + struct message_part *message_part_deserialize(pool_t pool, const void *data, size_t size, const char **error) { struct deserialize_context ctx; struct message_part *part; - /* make sure it looks valid */ - if (size < sizeof(struct serialized_message_part)) { - *error = "Not enough data for root"; + if (!check_size(size, error)) return NULL; - } - - if ((size % sizeof(struct serialized_message_part)) != 0) { - *error = "Incorrect data size"; - return NULL; - } - - if (size / sizeof(struct serialized_message_part) > UINT_MAX) { - *error = "Insane amount of data"; - return NULL; - } memset(&ctx, 0, sizeof(ctx)); ctx.pool = pool; @@ -219,21 +226,24 @@ } int message_part_serialize_update_header(void *data, size_t size, - struct message_size *hdr_size) + struct message_size *hdr_size, + const char **error) { struct serialized_message_part *spart = data; uoff_t first_pos; off_t pos_diff; size_t i, count; + unsigned int children; - /* make sure it looks valid */ - if (size < sizeof(struct serialized_message_part)) + if (!check_size(size, error)) return FALSE; if (hdr_size->physical_size >= OFF_T_MAX || spart->physical_pos >= OFF_T_MAX || - spart->header_physical_size >= OFF_T_MAX) + spart->header_physical_size >= OFF_T_MAX) { + *error = "Invalid data"; return FALSE; + } first_pos = spart->physical_pos; pos_diff = (off_t)hdr_size->physical_size - spart->header_physical_size; @@ -244,6 +254,7 @@ if (pos_diff != 0) { /* have to update all positions, but skip the first one */ + children = spart->children_count; count = (size / sizeof(struct serialized_message_part))-1; spart++; @@ -251,11 +262,21 @@ if (spart->physical_pos < first_pos || spart->physical_pos >= OFF_T_MAX) { /* invalid offset, might cause overflow */ + *error = "Invalid offset"; return FALSE; } + + children += spart->children_count; spart->physical_pos += pos_diff; } + + if (children != count) { + *error = t_strdup_printf("Size mismatch %u vs %u", + children, count); + return FALSE; + } } + return TRUE; } diff -r 411006be3c66 -r f7d0209bb7a6 src/lib-mail/message-part-serialize.h --- a/src/lib-mail/message-part-serialize.h Sat Jan 11 21:55:56 2003 +0200 +++ b/src/lib-mail/message-part-serialize.h Sun Jan 12 01:13:36 2003 +0200 @@ -14,7 +14,8 @@ /* Update header size in serialized struct message_part. */ int message_part_serialize_update_header(void *data, size_t size, - struct message_size *hdr_size); + struct message_size *hdr_size, + const char **error); /* Get message size from serialized struct message_part data. */ int message_part_deserialize_size(const void *data, size_t size,