[dovecot-cvs] dovecot/src/lib-index mail-custom-flags.c,1.15,1.16 mail-index-update.c,1.37,1.38 mail-modifylog.c,1.36,1.37

cras at procontrol.fi cras at procontrol.fi
Sun Dec 8 07:23:10 EET 2002


Update of /home/cvs/dovecot/src/lib-index
In directory danu:/tmp/cvs-serv19285/lib-index

Modified Files:
	mail-custom-flags.c mail-index-update.c mail-modifylog.c 
Log Message:
Added buffer API. Point is to hide all buffer writing behind this API which
verifies that nothing overflows. Much better than doing the same checks all
around the code, even if it is slightly slower.

Buffer reading is still mostly done directly, that isn't such a big security
risk and I can't think of a reasonable API for it anyway.



Index: mail-custom-flags.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-custom-flags.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- mail-custom-flags.c	1 Dec 2002 14:19:06 -0000	1.15
+++ mail-custom-flags.c	8 Dec 2002 05:23:08 -0000	1.16
@@ -40,7 +40,7 @@
 static int lock_file(MailCustomFlags *mcf, int type);
 
 static int index_cf_set_syscall_error(MailCustomFlags *mcf,
-				       const char *function)
+				      const char *function)
 {
 	i_assert(function != NULL);
 

Index: mail-index-update.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-update.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- mail-index-update.c	6 Dec 2002 01:09:22 -0000	1.37
+++ mail-index-update.c	8 Dec 2002 05:23:08 -0000	1.38
@@ -1,6 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
+#include "buffer.h"
 #include "istream.h"
 #include "ioloop.h"
 #include "rfc822-date.h"
@@ -130,30 +131,27 @@
         MailIndexDataRecordHeader *dest_hdr;
         MailIndexDataRecord *rec, *destrec;
 	MailDataField field;
-	void *mem;
+	Buffer *buf;
 	const void *src;
-	size_t pos, src_size;
+	size_t src_size;
+	size_t full_field_size;
 	int i;
 
 	i_assert(data_size <= UINT_MAX);
 
-	mem = p_malloc(update->pool, data_size);
+	buf = buffer_create_static_hard(update->pool, data_size);
 
 	/* set header */
-	dest_hdr = (MailIndexDataRecordHeader *) mem;
-	pos = sizeof(MailIndexDataRecordHeader);
-
+	dest_hdr = buffer_append_space(buf, sizeof(*dest_hdr));
 	memcpy(dest_hdr, &update->data_hdr, sizeof(*dest_hdr));
 	dest_hdr->data_size = data_size;
 
 	/* set fields */
 	rec = mail_index_data_lookup(update->index->data, update->rec, 0);
 	for (i = 0, field = 1; field != DATA_FIELD_LAST; i++, field <<= 1) {
-		destrec = (MailIndexDataRecord *) ((char *) mem + pos);
-
 		if (update->fields[i] != NULL) {
 			/* value was modified - use it */
-			destrec->full_field_size =
+			full_field_size =
 				get_max_align_size(update->field_sizes[i],
 						   update->field_extra_sizes[i],
 						   &extra_size);
@@ -161,24 +159,20 @@
 			src_size = update->field_sizes[i];
 		} else if (rec != NULL && rec->field == field) {
 			/* use the old value */
-			destrec->full_field_size = rec->full_field_size;
+			full_field_size = rec->full_field_size;
 			src = rec->data;
-			src_size = destrec->full_field_size;
+			src_size = rec->full_field_size;
 		} else {
 			/* the field doesn't exist, jump to next */
 			continue;
 		}
-		i_assert((destrec->full_field_size % MEM_ALIGN_SIZE) == 0);
-
-		/* make sure we don't overflow our buffer */
-		if (src_size > data_size || data_size - src_size < pos) {
-			i_panic("data file for index %s unexpectedly modified",
-				update->index->filepath);
-		}
-		memcpy(destrec->data, src, src_size);
+		i_assert((full_field_size % MEM_ALIGN_SIZE) == 0);
 
+		destrec = buffer_append_space(buf, SIZEOF_MAIL_INDEX_DATA +
+					      full_field_size);
 		destrec->field = field;
-		pos += DATA_RECORD_SIZE(destrec);
+		destrec->full_field_size = full_field_size;
+		memcpy(destrec->data, src, src_size);
 
 		if (rec != NULL && rec->field == field) {
 			rec = mail_index_data_next(update->index->data,
@@ -186,9 +180,7 @@
 		}
 	}
 
-	i_assert(pos <= data_size);
-
-	return mem;
+	return buffer_free_without_data(buf);
 }
 
 /* Append all the data at the end of the data file and update 
@@ -418,6 +410,7 @@
 	MessagePart *part;
 	MessageSize hdr_size, body_size;
 	Pool pool;
+	Buffer *buf;
 	const char *value;
 	size_t size;
 	uoff_t start_offset;
@@ -497,7 +490,11 @@
 
 		if (cache_fields & DATA_FIELD_MESSAGEPART) {
 			t_push();
-			value = message_part_serialize(part, &size);
+			buf = buffer_create_dynamic(data_stack_pool, 2048,
+						    (size_t)-1);
+			message_part_serialize(part, buf);
+
+			value = buffer_get_data(buf, &size);
 			update->index->update_field_raw(update,
 							DATA_FIELD_MESSAGEPART,
 							value, size);

Index: mail-modifylog.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-modifylog.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- mail-modifylog.c	25 Nov 2002 19:02:49 -0000	1.36
+++ mail-modifylog.c	8 Dec 2002 05:23:08 -0000	1.37
@@ -1,6 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
+#include "buffer.h"
 #include "file-lock.h"
 #include "file-set-size.h"
 #include "mmap-util.h"
@@ -1035,7 +1036,9 @@
 				unsigned int *expunges_before)
 {
 	ModifyLogRecord *rec;
-	ModifyLogExpunge *expunges, *arr;
+	ModifyLogExpunge *expunge;
+	Buffer *buf;
+	size_t count;
 	unsigned int before, max_records;
 
 	i_assert(log->index->lock_type != MAIL_LOCK_UNLOCK);
@@ -1067,7 +1070,9 @@
 	if (max_records > last_seq - first_seq + 1)
 		max_records = last_seq - first_seq + 1;
 
-	expunges = arr = t_malloc((max_records+1) * sizeof(ModifyLogExpunge));
+	i_assert((max_records+1) < SSIZE_T_MAX/sizeof(ModifyLogExpunge));
+	buf = buffer_create_static_hard(data_stack_pool, (max_records+1) *
+					sizeof(ModifyLogExpunge));
 
 	before = 0;
 	for (; rec != NULL; rec = modifylog_next(log, rec)) {
@@ -1087,18 +1092,19 @@
 				return NULL;
 			}
 
+			expunge = buffer_append_space(buf, sizeof(*expunge));
+
 			if (rec->seq1 < first_seq) {
 				/* partial initial match, update
 				   before-counter */
 				before += first_seq - rec->seq1;
-				arr->seq_count = rec->seq2 - first_seq + 1;
+				expunge->seq_count = rec->seq2 - first_seq + 1;
 			} else {
-				arr->seq_count = rec->seq2 - rec->seq1 + 1;
+				expunge->seq_count = rec->seq2 - rec->seq1 + 1;
 			}
 
-			arr->uid1 = rec->uid1;
-			arr->uid2 = rec->uid2;
-			arr++;
+			expunge->uid1 = rec->uid1;
+			expunge->uid2 = rec->uid2;
 		}
 
 		if (rec->seq1 <= last_seq) {
@@ -1113,14 +1119,19 @@
 		}
 	}
 
-	arr->uid1 = arr->uid2 = arr->seq_count = 0;
+	/* terminate the array */
+	expunge = buffer_append_space(buf, sizeof(*expunge));
+	memset(expunge, 0, sizeof(*expunge));
+
+	/* extract the array from buffer */
+	count = buffer_get_used_size(buf)/sizeof(ModifyLogExpunge);
+	expunge = buffer_free_without_data(buf);
 
 	/* sort the UID array, not including the terminating 0 */
-	qsort(expunges, (unsigned int) (arr - expunges),
-	      sizeof(ModifyLogExpunge), compare_expunge);
+	qsort(expunge, count-1, sizeof(ModifyLogExpunge), compare_expunge);
 
 	*expunges_before = before;
-	return expunges;
+	return expunge;
 }
 
 const ModifyLogExpunge *
@@ -1132,7 +1143,9 @@
 	/* pretty much copy&pasted from sequence code above ..
 	   kind of annoying */
 	ModifyLogRecord *rec;
-	ModifyLogExpunge *expunges, *arr;
+	ModifyLogExpunge *expunge;
+	Buffer *buf;
+	size_t count;
 	unsigned int before, max_records;
 
 	i_assert(log->index->lock_type != MAIL_LOCK_UNLOCK);
@@ -1164,7 +1177,9 @@
 	if (max_records > last_uid - first_uid + 1)
 		max_records = last_uid - first_uid + 1;
 
-	expunges = arr = t_malloc((max_records+1) * sizeof(ModifyLogExpunge));
+	i_assert((max_records+1) < SSIZE_T_MAX/sizeof(ModifyLogExpunge));
+	buf = buffer_create_static_hard(data_stack_pool, (max_records+1) *
+					sizeof(ModifyLogExpunge));
 
 	before = 0;
 	for (; rec != NULL; rec = modifylog_next(log, rec)) {
@@ -1184,21 +1199,27 @@
 				return NULL;
 			}
 
-			arr->uid1 = rec->uid1;
-			arr->uid2 = rec->uid2;
-			arr->seq_count = rec->seq2 -rec->seq1 + 1;
-			arr++;
+			expunge = buffer_append_space(buf, sizeof(*expunge));
+
+			expunge->uid1 = rec->uid1;
+			expunge->uid2 = rec->uid2;
+			expunge->seq_count = rec->seq2 -rec->seq1 + 1;
 		}
 	}
 
-	arr->uid1 = arr->uid2 = arr->seq_count = 0;
+	/* terminate the array */
+	expunge = buffer_append_space(buf, sizeof(*expunge));
+	memset(expunge, 0, sizeof(*expunge));
+
+	/* extract the array from buffer */
+	count = buffer_get_used_size(buf)/sizeof(ModifyLogExpunge);
+	expunge = buffer_free_without_data(buf);
 
 	/* sort the UID array, not including the terminating 0 */
-	qsort(expunges, (unsigned int) (arr - expunges),
-	      sizeof(ModifyLogExpunge), compare_expunge);
+	qsort(expunge, count-1, sizeof(ModifyLogExpunge), compare_expunge);
 
 	*expunges_before = before;
-	return expunges;
+	return expunge;
 }
 
 static unsigned int modifylog_file_get_expunge_count(ModifyLogFile *file)




More information about the dovecot-cvs mailing list