dovecot-2.0: zlib: If reading corrupted compressed mail files, l...

dovecot at dovecot.org dovecot at dovecot.org
Sat Mar 6 13:33:36 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/def12863b620
changeset: 10846:def12863b620
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Mar 06 13:33:33 2010 +0200
description:
zlib: If reading corrupted compressed mail files, log an error.

diffstat:

 src/plugins/imap-zlib/imap-zlib-plugin.c |   2 +-
 src/plugins/zlib/istream-bzlib.c         |  13 +++++++++++--
 src/plugins/zlib/istream-zlib.c          |  36 ++++++++++++++++++++++++++++--------
 src/plugins/zlib/istream-zlib.h          |   6 +++---
 src/plugins/zlib/zlib-plugin.c           |   4 ++--
 src/plugins/zlib/zlib-plugin.h           |   3 ++-
 6 files changed, 47 insertions(+), 17 deletions(-)

diffs (227 lines):

diff -r 95f5ea024043 -r def12863b620 src/plugins/imap-zlib/imap-zlib-plugin.c
--- a/src/plugins/imap-zlib/imap-zlib-plugin.c	Sat Mar 06 13:14:54 2010 +0200
+++ b/src/plugins/imap-zlib/imap-zlib-plugin.c	Sat Mar 06 13:33:33 2010 +0200
@@ -111,7 +111,7 @@
 
 	old_input = client->input;
 	old_output = client->output;
-	client->input = handler->create_istream(old_input);
+	client->input = handler->create_istream(old_input, FALSE);
 	client->output = handler->create_ostream(old_output, level);
 	i_stream_unref(&old_input);
 	o_stream_unref(&old_output);
diff -r 95f5ea024043 -r def12863b620 src/plugins/zlib/istream-bzlib.c
--- a/src/plugins/zlib/istream-bzlib.c	Sat Mar 06 13:14:54 2010 +0200
+++ b/src/plugins/zlib/istream-bzlib.c	Sat Mar 06 13:33:33 2010 +0200
@@ -17,6 +17,7 @@
 	uoff_t eof_offset;
 	size_t prev_size;
 
+	unsigned int log_errors:1;
 	unsigned int marked:1;
 	unsigned int zs_closed:1;
 };
@@ -76,8 +77,9 @@
 				stream->istream.stream_errno =
 					stream->parent->stream_errno;
 			} else {
-				/* unexpected eof */
 				i_assert(stream->parent->eof);
+				if (zstream->log_errors)
+					i_error("bzlib: unexpected EOF");
 				stream->istream.stream_errno = EINVAL;
 			}
 			return -1;
@@ -107,7 +109,13 @@
 	case BZ_PARAM_ERROR:
 		i_unreached();
 	case BZ_DATA_ERROR:
+		if (zstream->log_errors)
+			i_error("bzlib: corrupted data");
+		stream->istream.stream_errno = EINVAL;
+		return -1;
 	case BZ_DATA_ERROR_MAGIC:
+		if (zstream->log_errors)
+			i_error("bzlib: wrong magic in header (not bz2 file?)");
 		stream->istream.stream_errno = EINVAL;
 		return -1;
 	case BZ_MEM_ERROR:
@@ -253,12 +261,13 @@
 	i_stream_bzlib_reset(zstream);
 }
 
-struct istream *i_stream_create_bz2(struct istream *input)
+struct istream *i_stream_create_bz2(struct istream *input, bool log_errors)
 {
 	struct bzlib_istream *zstream;
 
 	zstream = i_new(struct bzlib_istream, 1);
 	zstream->eof_offset = (uoff_t)-1;
+	zstream->log_errors = log_errors;
 
 	i_stream_bzlib_init(zstream);
 
diff -r 95f5ea024043 -r def12863b620 src/plugins/zlib/istream-zlib.c
--- a/src/plugins/zlib/istream-zlib.c	Sat Mar 06 13:14:54 2010 +0200
+++ b/src/plugins/zlib/istream-zlib.c	Sat Mar 06 13:33:33 2010 +0200
@@ -30,6 +30,7 @@
 	uint32_t crc32;
 
 	unsigned int gz:1;
+	unsigned int log_errors:1;
 	unsigned int marked:1;
 	unsigned int header_read:1;
 	unsigned int trailer_read:1;
@@ -57,8 +58,11 @@
 	ret = i_stream_read_data(stream->parent, &data, &size,
 				 zstream->prev_size);
 	if (size == zstream->prev_size) {
-		if (ret == -1)
+		if (ret == -1) {
+			if (zstream->log_errors)
+				i_error("zlib: missing gz header");
 			stream->istream.stream_errno = EINVAL;
+		}
 		return ret;
 	}
 	zstream->prev_size = size;
@@ -69,6 +73,8 @@
 
 	if (data[0] != GZ_MAGIC1 || data[1] != GZ_MAGIC2) {
 		/* missing gzip magic header */
+		if (zstream->log_errors)
+			i_error("zlib: wrong magic in header (not gz file?)");
 		stream->istream.stream_errno = EINVAL;
 		return -1;
 	}
@@ -119,8 +125,11 @@
 	ret = i_stream_read_data(stream->parent, &data, &size,
 				 GZ_TRAILER_SIZE-1);
 	if (size == zstream->prev_size) {
-		if (ret == -1)
+		if (ret == -1) {
+			if (zstream->log_errors)
+				i_error("zlib: missing gz trailer");
 			stream->istream.stream_errno = EINVAL;
+		}
 		return ret;
 	}
 	zstream->prev_size = size;
@@ -129,6 +138,8 @@
 		return 0;
 
 	if (data_get_uint32(data) != zstream->crc32) {
+		if (zstream->log_errors)
+			i_error("zlib: gz trailer has wrong CRC value");
 		stream->istream.stream_errno = EINVAL;
 		return -1;
 	}
@@ -199,8 +210,9 @@
 				stream->istream.stream_errno =
 					stream->parent->stream_errno;
 			} else {
-				/* unexpected eof */
 				i_assert(stream->parent->eof);
+				if (zstream->log_errors)
+					i_error("zlib: unexpected EOF");
 				stream->istream.stream_errno = EINVAL;
 			}
 			return -1;
@@ -230,7 +242,13 @@
 	case Z_OK:
 		break;
 	case Z_NEED_DICT:
+		if (zstream->log_errors)
+			i_error("zlib: can't read file without dict");
+		stream->istream.stream_errno = EINVAL;
+		return -1;
 	case Z_DATA_ERROR:
+		if (zstream->log_errors)
+			i_error("zlib: corrupted data");
 		stream->istream.stream_errno = EINVAL;
 		return -1;
 	case Z_MEM_ERROR:
@@ -387,13 +405,15 @@
 	i_stream_zlib_reset(zstream);
 }
 
-static struct istream *i_stream_create_zlib(struct istream *input, bool gz)
+static struct istream *
+i_stream_create_zlib(struct istream *input, bool gz, bool log_errors)
 {
 	struct zlib_istream *zstream;
 
 	zstream = i_new(struct zlib_istream, 1);
 	zstream->eof_offset = (uoff_t)-1;
 	zstream->gz = gz;
+	zstream->log_errors = log_errors;
 
 	i_stream_zlib_init(zstream);
 
@@ -412,13 +432,13 @@
 			       i_stream_get_fd(input));
 }
 
-struct istream *i_stream_create_gz(struct istream *input)
+struct istream *i_stream_create_gz(struct istream *input, bool log_errors)
 {
-	return i_stream_create_zlib(input, TRUE);
+	return i_stream_create_zlib(input, TRUE, log_errors);
 }
 
-struct istream *i_stream_create_deflate(struct istream *input)
+struct istream *i_stream_create_deflate(struct istream *input, bool log_errors)
 {
-	return i_stream_create_zlib(input, FALSE);
+	return i_stream_create_zlib(input, FALSE, log_errors);
 }
 #endif
diff -r 95f5ea024043 -r def12863b620 src/plugins/zlib/istream-zlib.h
--- a/src/plugins/zlib/istream-zlib.h	Sat Mar 06 13:14:54 2010 +0200
+++ b/src/plugins/zlib/istream-zlib.h	Sat Mar 06 13:33:33 2010 +0200
@@ -1,8 +1,8 @@
 #ifndef ISTREAM_ZLIB_H
 #define ISTREAM_ZLIB_H
 
-struct istream *i_stream_create_gz(struct istream *input);
-struct istream *i_stream_create_deflate(struct istream *input);
-struct istream *i_stream_create_bz2(struct istream *input);
+struct istream *i_stream_create_gz(struct istream *input, bool log_errors);
+struct istream *i_stream_create_deflate(struct istream *input, bool log_errors);
+struct istream *i_stream_create_bz2(struct istream *input, bool log_errors);
 
 #endif
diff -r 95f5ea024043 -r def12863b620 src/plugins/zlib/zlib-plugin.c
--- a/src/plugins/zlib/zlib-plugin.c	Sat Mar 06 13:14:54 2010 +0200
+++ b/src/plugins/zlib/zlib-plugin.c	Sat Mar 06 13:33:33 2010 +0200
@@ -162,7 +162,7 @@
 		}
 
 		input = imail->data.stream;
-		imail->data.stream = handler->create_istream(input);
+		imail->data.stream = handler->create_istream(input, TRUE);
 		i_stream_unref(&input);
 	}
 	return index_mail_init_stream(imail, hdr_size, body_size, stream_r);
@@ -340,7 +340,7 @@
 			return -1;
 		}
 		input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
-		box->input = handler->create_istream(input);
+		box->input = handler->create_istream(input, TRUE);
 		i_stream_unref(&input);
 		box->flags |= MAILBOX_FLAG_READONLY;
 	}
diff -r 95f5ea024043 -r def12863b620 src/plugins/zlib/zlib-plugin.h
--- a/src/plugins/zlib/zlib-plugin.h	Sat Mar 06 13:14:54 2010 +0200
+++ b/src/plugins/zlib/zlib-plugin.h	Sat Mar 06 13:33:33 2010 +0200
@@ -5,7 +5,8 @@
 	const char *name;
 	const char *ext;
 	bool (*is_compressed)(struct istream *input);
-	struct istream *(*create_istream)(struct istream *input);
+	struct istream *(*create_istream)(struct istream *input,
+					  bool log_errors);
 	struct ostream *(*create_ostream)(struct ostream *output, int level);
 };
 


More information about the dovecot-cvs mailing list