dovecot-1.1: zlib plugin: Uncompress if the message begins with ...

dovecot at dovecot.org dovecot at dovecot.org
Sun May 25 00:47:31 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.1/rev/0b9a5a7a0b3e
changeset: 7535:0b9a5a7a0b3e
user:      Timo Sirainen <tss at iki.fi>
date:      Sun May 25 00:47:27 2008 +0300
description:
zlib plugin: Uncompress if the message begins with zlib header instead of
looking at the 'Z' flag. This fixes copying with hard links. Based on a
patch by Richard Platel.

diffstat:

1 file changed, 18 insertions(+), 7 deletions(-)
src/plugins/zlib/zlib-plugin.c |   25 ++++++++++++++++++-------

diffs (51 lines):

diff -r 9c781d042afe -r 0b9a5a7a0b3e src/plugins/zlib/zlib-plugin.c
--- a/src/plugins/zlib/zlib-plugin.c	Sun May 25 00:34:03 2008 +0300
+++ b/src/plugins/zlib/zlib-plugin.c	Sun May 25 00:47:27 2008 +0300
@@ -26,18 +26,32 @@ static MODULE_CONTEXT_DEFINE_INIT(zlib_s
 				  &mail_storage_module_register);
 static MODULE_CONTEXT_DEFINE_INIT(zlib_mail_module, &mail_module_register);
 
+static int zlib_mail_is_compressed(struct istream *mail)
+{
+	const unsigned char *zheader;
+	size_t header_size;
+
+	/* Peek in to the mail and see if it looks like it's compressed
+	   (it has the correct 2 byte zlib header). This also means that users
+	   can try to exploit security holes in zlib by APPENDing a specially
+	   crafted mail. So let's hope zlib is free of holes. */
+	if (i_stream_read_data(mail, &zheader, &header_size, 2) <= 0)
+		return 0;
+	i_stream_seek(mail, 0);
+
+	return header_size >= 2 && zheader &&
+		zheader[0] == 31 && zheader[1] == 139;
+}
+
 static int zlib_maildir_get_stream(struct mail *_mail,
 				   struct message_size *hdr_size,
 				   struct message_size *body_size,
 				   struct istream **stream_r)
 {
-	struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
 	struct mail_private *mail = (struct mail_private *)_mail;
 	struct index_mail *imail = (struct index_mail *)mail;
 	union mail_module_context *zmail = ZLIB_MAIL_CONTEXT(mail);
 	struct istream *input;
-	const char *fname, *p;
-        enum maildir_uidlist_rec_flag flags;
 	int fd;
 
 	if (imail->data.stream != NULL) {
@@ -49,10 +63,7 @@ static int zlib_maildir_get_stream(struc
 		return -1;
 	i_assert(input == imail->data.stream);
 
-	fname = maildir_uidlist_lookup(mbox->uidlist, _mail->uid, &flags);
-	p = fname == NULL ? NULL : strstr(fname, ":2,");
-	if (p != NULL && strchr(p + 3, 'Z') != NULL) {
-		/* has a Z flag - it's compressed */
+	if (zlib_mail_is_compressed(imail->data.stream)) {
 		fd = dup(i_stream_get_fd(imail->data.stream));
 		if (fd == -1)
 			i_error("zlib plugin: dup() failed: %m");


More information about the dovecot-cvs mailing list