changeset 954:f7d0209bb7a6 HEAD

Do some more sanity checking when updating cached message_part. If anything fails, log the error and set index corrupted.
author Timo Sirainen <tss@iki.fi>
date Sun, 12 Jan 2003 01:13:36 +0200
parents 411006be3c66
children 1fd572d68422
files src/lib-index/mbox/mbox-sync-full.c src/lib-mail/message-part-serialize.c src/lib-mail/message-part-serialize.h
diffstat 3 files changed, 46 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- 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;
 	}
--- 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;
 }
 
--- 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,