Bug#747561: imtest hangs when receiving long responses over SSL

Tom Yu tlyu at MIT.EDU
Sat May 10 00:37:12 UTC 2014


Package: cyrus-clients-2.4
Version: 2.4.12-2
Tags: upstream

When using imtest with an SSL connection ("imtest -s ...") against an
Exchange IMAP server, long responses from the server sometimes cause
the program to hang after only partially printing the response, often
before printing a newline.  This makes using imtest with the Gnus
nnimap back end mostly useless against my Exchange server.  One such
long server response can result from running the "UID SEARCH ALL"
command on a mailbox containing thousands of messages.  A given
response text will not always consistently hang the program, which
implies a race condition.  Sending any input to imtest, e.g., a NOOP
command, will wake up imtest and cause it to print the remainder of
the response.  Unsolicited responses from the server, such as an
inactivity timeout, can also cause the remainder of the response to be
printed.

Using the "-v" flag to imtest shows that prior to the hang, a read
returns well over 4k bytes, but the printed output corresponding to
that read prints exactly 4096 bytes before hanging.  The cause is
imtest/imtest.c:interactive() inappropriately using the condition
(pin->cnt > 0) to determine whether to continue looping calling
lib/prot.c:prot_read().

The buffer that prot_read() uses to read from SSL_read() is exactly
4096 bytes long (PROT_BUFSIZE).  When an SSL record with a plaintext
larger than 4096 bytes arrives, repeated calls to prot_read() by
interactive() will eventually lead to pin->cnt (the protstream handle
for the input from the IMAP socket) reaching zero while data remains
to be read from the SSL buffers.  Further calls to prot_read() will
actually not block in this condition, but the readable condition is
possibly already cleared on the socket file descriptor, depending on
timing races with other output from the server.  If the socket
readable condition is cleared when pin->cnt reaches zero, the program
blocks in select() until there is some user input or an unsolicited
server response.  It is possible that the Exchange server needs to
have a very large MTU configured for this bug to trigger.

The fix is to call SSL_pending() when pin->cnt reaches zero to
determine if there really is no more input to read.

I found this bug in the Ubuntu 12.04.4 version of this package, but
there are no Ubuntu-specific changes to the package.  A debdiff
against the Debian unstable version (2.4.17+caldav~beta9-3) doesn't
show any differences in the relevant code.  By code inspection, the
upstream development sources also still have this bug.

I have a debdiff of a tested proposed patch that I will send in a
separate message.



More information about the Pkg-Cyrus-imapd-Debian-devel mailing list