Fixed infinite loop in message parsing if message ends with

"--boundary" and CR (without LF). Messages saved via SMTP/LMTP can't
  trigger this, because messages must end with an "LF.". A user could
  trigger this for him/herself though.
- lmtp: Client was sometimes disconnected before all the output was
  sent to it.
- replicator: Database wasn't being exported to disk every 15 minutes
  as it should have. Instead it was being imported, causing "doveadm
  replicator remove" commands to not work very well.
This commit is contained in:
Michal Hlavinka 2013-11-20 17:12:58 +01:00
parent 3ecaa4f55d
commit 680863f7be
8 changed files with 138 additions and 29 deletions

1
.gitignore vendored
View File

@ -74,3 +74,4 @@ pigeonhole-snap0592366457df.tar.bz2
/dovecot-2.2.6.tar.gz
/dovecot-2.2-pigeonhole-0.4.2.tar.gz
/dovecot-2.2.7.tar.gz
/dovecot-2.2.8.tar.gz

View File

@ -1,24 +0,0 @@
# HG changeset patch
# User Timo Sirainen <tss@iki.fi>
# Date 1383514035 -7200
# Node ID 10c0aae82d0dee0b0107c2262db50d5f6984c181
# Parent 653d5a81a22e73ff91264f7e7277b1c0206574ec
ostream: Mark stream closed before handling its callback to avoid infinite loops.
The callback could call o_stream_copy_error_from_parent(), which in turn
would try to close the same ostream again.
diff -r 653d5a81a22e -r 10c0aae82d0d src/lib/ostream.c
--- a/src/lib/ostream.c Sun Nov 03 22:04:53 2013 +0200
+++ b/src/lib/ostream.c Sun Nov 03 23:27:15 2013 +0200
@@ -46,8 +46,8 @@
static void o_stream_close_full(struct ostream *stream, bool close_parents)
{
if (!stream->closed) {
+ stream->closed = TRUE;
io_stream_close(&stream->real_stream->iostream, close_parents);
- stream->closed = TRUE;
}
if (stream->stream_errno == 0)

View File

@ -0,0 +1,35 @@
# HG changeset patch
# User Timo Sirainen <tss@iki.fi>
# Date 1384952846 -7200
# Node ID 47923cfd4b5616f943c8e043c09e64e94b5c24f9
# Parent 4ef184875799baa65b4b6048ccde49eefbfd9050
lib-storage: mail_get_headers*() returned only the first header from cache.
diff -r 4ef184875799 -r 47923cfd4b56 src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c Wed Nov 20 14:50:53 2013 +0200
+++ b/src/lib-storage/index/index-mail-headers.c Wed Nov 20 15:07:26 2013 +0200
@@ -603,7 +603,7 @@
unsigned char *data;
unsigned int field_idx;
string_t *dest;
- size_t i, len;
+ size_t i, len, len2;
int ret;
ARRAY(const char *) header_values;
@@ -657,10 +657,10 @@
while (i < len && IS_LWSP(data[i])) i++;
/* @UNSAFE */
- len = get_header_size(dest, i);
- data[i + len] = '\0';
+ len2 = get_header_size(dest, i);
+ data[i + len2] = '\0';
value = (const char *)data + i;
- i += len + 1;
+ i += len2 + 1;
array_append(&header_values, &value, 1);
}

View File

@ -0,0 +1,24 @@
# HG changeset patch
# User Timo Sirainen <tss@iki.fi>
# Date 1384951853 -7200
# Node ID 4ef184875799baa65b4b6048ccde49eefbfd9050
# Parent a91437fe94b67fc0b5ef8f3177a9ebe1deccc9e3
lib-storage: mail_get_*header*() still didn't handle cached values correctly.
If header ends with ":", the ":" shouldn't be returned as part of the value.
diff -r a91437fe94b6 -r 4ef184875799 src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c Wed Nov 20 14:38:55 2013 +0200
+++ b/src/lib-storage/index/index-mail-headers.c Wed Nov 20 14:50:53 2013 +0200
@@ -653,8 +653,8 @@
/* cached. skip "header name: " parts in dest. */
for (i = 0; i < len; i++) {
if (data[i] == ':') {
- while (IS_LWSP(data[i+1])) i++;
- if (i+1 != len) i++;
+ i++;
+ while (i < len && IS_LWSP(data[i])) i++;
/* @UNSAFE */
len = get_header_size(dest, i);

View File

@ -0,0 +1,32 @@
# HG changeset patch
# User Timo Sirainen <tss@iki.fi>
# Date 1384951135 -7200
# Node ID a91437fe94b67fc0b5ef8f3177a9ebe1deccc9e3
# Parent f4eb4b5884b2e89e146a32b2d1db1f14f753008f
lib-storage: mail_get_*header*() were unnecessarily looking up the headers twice.
diff -r f4eb4b5884b2 -r a91437fe94b6 src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c Wed Nov 20 14:37:44 2013 +0200
+++ b/src/lib-storage/index/index-mail-headers.c Wed Nov 20 14:38:55 2013 +0200
@@ -760,6 +760,9 @@
mail_cache_set_corrupted(_mail->box->cache,
"Broken header %s for mail UID %u",
field, _mail->uid);
+ /* retry by parsing the full header */
+ } else {
+ break;
}
}
return ret;
@@ -788,6 +791,9 @@
mail_cache_set_corrupted(_mail->box->cache,
"Broken header %s for mail UID %u",
field, _mail->uid);
+ /* retry by parsing the full header */
+ } else {
+ break;
}
}
*value_r = list[0];

View File

@ -0,0 +1,23 @@
# HG changeset patch
# User Timo Sirainen <tss@iki.fi>
# Date 1384951064 -7200
# Node ID f4eb4b5884b2e89e146a32b2d1db1f14f753008f
# Parent 4a0c03f98ca350634430e5c3bd5f8e5efc030a45
lib-storage: mail_get_*header*() didn't remove leading whitespace for headers from cache.
But it was removed when the headers were found by parsing the full header.
diff -r 4a0c03f98ca3 -r f4eb4b5884b2 src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c Tue Nov 19 23:18:11 2013 +0200
+++ b/src/lib-storage/index/index-mail-headers.c Wed Nov 20 14:37:44 2013 +0200
@@ -653,7 +653,8 @@
/* cached. skip "header name: " parts in dest. */
for (i = 0; i < len; i++) {
if (data[i] == ':') {
- if (i+1 != len && data[++i] == ' ') i++;
+ while (IS_LWSP(data[i+1])) i++;
+ if (i+1 != len) i++;
/* @UNSAFE */
len = get_header_size(dest, i);

View File

@ -3,9 +3,9 @@
Summary: Secure imap and pop3 server
Name: dovecot
Epoch: 1
Version: 2.2.7
Version: 2.2.8
%global prever %{nil}
Release: 2%{?dist}
Release: 1%{?dist}
#dovecot itself is MIT, a few sources are PD, pigeonhole is LGPLv2
License: MIT and LGPLv2
Group: System Environment/Daemons
@ -35,7 +35,11 @@ Patch5: dovecot-2.1-privatetmp.patch
#wait for network
Patch6: dovecot-2.1.10-waitonline.patch
Patch7: dovecot-2.2.7-10c0aae82d0d.patch
Patch7: dovecot-2.2.8-f4eb4b5884b2.patch
Patch8: dovecot-2.2.8-a91437fe94b6.patch
Patch9: dovecot-2.2.8-4ef184875799.patch
Patch10: dovecot-2.2.8-47923cfd4b56.patch
Source15: prestartscript
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@ -132,7 +136,10 @@ This package provides the development files for dovecot.
%patch4 -p1 -b .reload
%patch5 -p1 -b .privatetmp
%patch6 -p1 -b .waitonline
%patch7 -p1 -b .10c0aae82d0d
%patch7 -p1 -b .f4eb4b5884b2
%patch8 -p1 -b .a91437fe94b6
%patch9 -p1 -b .4ef184875799
%patch10 -p1 -b .47923cfd4b56
sed -i '/DEFAULT_INCLUDES *=/s|$| '"$(pkg-config --cflags libclucene-core)|" src/plugins/fts-lucene/Makefile.in
%build
@ -486,6 +493,17 @@ make check
%{_libdir}/%{name}/dict/libdriver_pgsql.so
%changelog
* Wed Nov 20 2013 Michal Hlavinka <mhlavink@redhat.com> - 1:2.2.8-1
- Fixed infinite loop in message parsing if message ends with
"--boundary" and CR (without LF). Messages saved via SMTP/LMTP can't
trigger this, because messages must end with an "LF.". A user could
trigger this for him/herself though.
- lmtp: Client was sometimes disconnected before all the output was
sent to it.
- replicator: Database wasn't being exported to disk every 15 minutes
as it should have. Instead it was being imported, causing "doveadm
replicator remove" commands to not work very well.
* Thu Nov 14 2013 Michal Hlavinka <mhlavink@redhat.com> - 1:2.2.7-2
- fix ostream infinite loop (#1029906)

View File

@ -1,2 +1,2 @@
d2c7c83acc21f3dcab652868d40522e0 dovecot-2.2.7.tar.gz
c1594f7ffa470b6134a94c59fd85bbe8 dovecot-2.2.8.tar.gz
e8cb4976db9811d37e9d870f2f75ffef dovecot-2.2-pigeonhole-0.4.2.tar.gz