[PATCH] imtest hangs when receiving long responses over SSL

Ken Murchison murch at andrew.cmu.edu
Thu May 15 13:41:05 EDT 2014

Hi Tom,

Thanks for the patch.  I tweaked it slightly and committed it with you 
as the author.

On 05/12/2014 05:52 PM, Tom Yu wrote:
> This is based on behavior in the Debian cyrus-imapd-2.4 source package
> version 2.4.12-2.  I have included a patch against that version.  By
> code inspection, the same bug very probably still exists in master.  I
> have also reported this in the Debian bug tracker:
>      https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=747561
> 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.  An
> architecturally cleaner fix might be possible, but I imagine that
> involves rewriting interactive() to work with prot_select().

Kenneth Murchison
Principal Systems Software Engineer
Carnegie Mellon University

More information about the Cyrus-devel mailing list