changeset 6427:c242677f2aa9 HEAD

Don't crash if duplicate database contains broken entries.
author Timo Sirainen <tss@iki.fi>
date Sun, 16 Sep 2007 13:51:51 +0300
parents f32ee254913d
children 7cad076906eb
files src/deliver/duplicate.c
diffstat 1 files changed, 16 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/deliver/duplicate.c	Sun Sep 16 13:42:08 2007 +0300
+++ b/src/deliver/duplicate.c	Sun Sep 16 13:51:51 2007 +0300
@@ -15,6 +15,7 @@
 
 #define DUPLICATE_PATH "~/.dovecot.lda-dupes"
 #define COMPRESS_PERCENTAGE 10
+#define DUPLICATE_BUFSIZE 4096
 
 struct duplicate {
 	const void *id;
@@ -84,6 +85,7 @@
 	size_t size;
 	time_t stamp;
 	unsigned int offset, id_size, user_size, change_count;
+	bool broken = FALSE;
 
 	fd = open(file->path, O_RDONLY);
 	if (fd == -1) {
@@ -94,7 +96,7 @@
 	}
 
 	/* <timestamp> <id_size> <user_size> <id> <user> */
-	input = i_stream_create_fd(fd, 4096, FALSE);
+	input = i_stream_create_fd(fd, DUPLICATE_BUFSIZE, FALSE);
 
 	change_count = 0;
 	while (i_stream_read_data(input, &data, &size, sizeof(stamp) +
@@ -109,9 +111,18 @@
 
 		i_stream_skip(input, offset);
 
+		if (id_size == 0 || user_size == 0 ||
+		    id_size > DUPLICATE_BUFSIZE ||
+		    user_size > DUPLICATE_BUFSIZE) {
+			i_error("broken duplicate file %s", file->path);
+			broken = TRUE;
+			break;
+		}
+
 		if (i_stream_read_data(input, &data, &size,
 				       id_size + user_size - 1) <= 0) {
 			i_error("unexpected end of file in %s", file->path);
+			broken = TRUE;
 			break;
 		}
 
@@ -142,6 +153,10 @@
 	i_stream_unref(&input);
 	if (close(fd) < 0)
 		i_error("close(%s) failed: %m", file->path);
+	if (broken) {
+		if (unlink(file->path) < 0 && errno != ENOENT)
+			i_error("unlink(%s) failed: %m", file->path);
+	}
 	return 0;
 }