IMAP session hangs on 8k-long commands if COMPRESS=DEFLATE is enabled
Hi there,
Dovecot 2.3.7 appears to hang when the client sends a long command after enabling the IMAP COMPRESS extension [RFC 4978]. PoC script attached along with the doveconf(1) output.
Without COMPRESS=DEFLATE, and with the default ‘imap_max_line_length’ value (64k) I'm able send commands up to 65539 bytes long (that's 3 bytes more than 2¹⁶, so maybe the leading tag and the trailing CRLF aren't counted), after which Dovecot rightfully replies with tagged BAD responses.
$ COMPRESS=n /tmp/many-fetch.pl 65539
[…]
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65539 bytes]
S: x OK Fetch completed (0.005 + 0.001 + 0.004 secs).
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65540 bytes]
S: x BAD Error in IMAP command UID FETCH: IMAP command line too large (0.001 + 0.001 secs).
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65541 bytes]
S: x BAD Error in IMAP command UID FETCH: IMAP command line too large (0.001 + 0.001 secs).
With COMPRESS=DEFLATE however, the server never sends anything back when the command size exceeds 8192 bytes:
$ COMPRESS=y /tmp/many-fetch.pl 8192
[…]
S: x OK [READ-ONLY] Examine completed (0.001 + 0.000 secs).
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8191 bytes]
S: x OK Fetch completed (0.001 + 0.000 secs).
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8192 bytes]
S: x OK Fetch completed (0.001 + 0.000 secs).
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8193 bytes]
[ _hangs until the server terminates the session for inactivity_ ]
S: * BYE Disconnected for inactivity.
strace(1) show that Dovecot didn't send the response, even though the server log indicates that it's able to fully read the command.
Interestingly, when setting ‘imap_max_line_length’ to 4096, the server also hangs after receiving a command of size >4096 bytes (instead of replying with a tagged BAD response).
$ COMPRESS=y /tmp/many-fetch.pl 4096
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4095 bytes]
S: x OK Fetch completed (0.001 + 0.000 secs).
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4096 bytes]
S: x OK Fetch completed (0.001 + 0.000 secs).
C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4097 bytes]
[ _hangs until the server terminates the session for inactivity_ ]
I'm also able to reproduce the buggy behavior against Dovecot versions found in other Debian releases. It's identical with 2.3.4 (Buster), the server also hang past 8192 bytes. 2.2.27 (Stretch) and 2.2.13 (Jessie) are able to send replies to 8k-long commands, but hang past 65536 bytes. For all 3 releases, without COMPRESS=DEFLATE Dovecot doesn't hang and rightfully sends tagged BAD responses to commands of size >65539 bytes.
So while the hanging behavior appears to be a long-standing bug, the fact that's it's now hit at min($imap_max_line_length, 8192) instead of $imap_max_line_length seems to be a regression from somewhere between 2.2.27 and 2.3.4.
Cheers,
Guilhem.
On 13/11/2019 00:22, Guilhem Moulin via dovecot wrote:
Hi there,
Dovecot 2.3.7 appears to hang when the client sends a long command after enabling the IMAP COMPRESS extension [RFC 4978]. PoC script attached along with the doveconf(1) output.
Without COMPRESS=DEFLATE, and with the default ‘imap_max_line_length’ value (64k) I'm able send commands up to 65539 bytes long (that's 3 bytes more than 2¹⁶, so maybe the leading tag and the trailing CRLF aren't counted), after which Dovecot rightfully replies with tagged BAD responses.
$ COMPRESS=n /tmp/many-fetch.pl 65539 […] C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65539 bytes] S: x OK Fetch completed (0.005 + 0.001 + 0.004 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65540 bytes] S: x BAD Error in IMAP command UID FETCH: IMAP command line too large (0.001 + 0.001 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65541 bytes] S: x BAD Error in IMAP command UID FETCH: IMAP command line too large (0.001 + 0.001 secs).
With COMPRESS=DEFLATE however, the server never sends anything back when the command size exceeds 8192 bytes:
$ COMPRESS=y /tmp/many-fetch.pl 8192 […] S: x OK [READ-ONLY] Examine completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8191 bytes] S: x OK Fetch completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8192 bytes] S: x OK Fetch completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8193 bytes] [ _hangs until the server terminates the session for inactivity_ ] S: * BYE Disconnected for inactivity.
strace(1) show that Dovecot didn't send the response, even though the server log indicates that it's able to fully read the command.
Interestingly, when setting ‘imap_max_line_length’ to 4096, the server also hangs after receiving a command of size >4096 bytes (instead of replying with a tagged BAD response).
$ COMPRESS=y /tmp/many-fetch.pl 4096 C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4095 bytes] S: x OK Fetch completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4096 bytes] S: x OK Fetch completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4097 bytes] [ _hangs until the server terminates the session for inactivity_ ]
I'm also able to reproduce the buggy behavior against Dovecot versions found in other Debian releases. It's identical with 2.3.4 (Buster), the server also hang past 8192 bytes. 2.2.27 (Stretch) and 2.2.13 (Jessie) are able to send replies to 8k-long commands, but hang past 65536 bytes. For all 3 releases, without COMPRESS=DEFLATE Dovecot doesn't hang and rightfully sends tagged BAD responses to commands of size >65539 bytes.
So while the hanging behavior appears to be a long-standing bug, the fact that's it's now hit at min($imap_max_line_length, 8192) instead of $imap_max_line_length seems to be a regression from somewhere between 2.2.27 and 2.3.4.
I was able to confirm this problem with the current master. Tracking internally as DOP-1591.
Regards,
Stephan.
On 07/12/2019 00:25 Stephan Bosch via dovecot <dovecot@dovecot.org> wrote:
On 13/11/2019 00:22, Guilhem Moulin via dovecot wrote:
Hi there,
Dovecot 2.3.7 appears to hang when the client sends a long command after enabling the IMAP COMPRESS extension [RFC 4978]. PoC script attached along with the doveconf(1) output.
Without COMPRESS=DEFLATE, and with the default ‘imap_max_line_length’ value (64k) I'm able send commands up to 65539 bytes long (that's 3 bytes more than 2¹⁶, so maybe the leading tag and the trailing CRLF aren't counted), after which Dovecot rightfully replies with tagged BAD responses.
$ COMPRESS=n /tmp/many-fetch.pl 65539 […] C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65539 bytes] S: x OK Fetch completed (0.005 + 0.001 + 0.004 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65540 bytes] S: x BAD Error in IMAP command UID FETCH: IMAP command line too large (0.001 + 0.001 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [65541 bytes] S: x BAD Error in IMAP command UID FETCH: IMAP command line too large (0.001 + 0.001 secs).
With COMPRESS=DEFLATE however, the server never sends anything back when the command size exceeds 8192 bytes:
$ COMPRESS=y /tmp/many-fetch.pl 8192 […] S: x OK [READ-ONLY] Examine completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8191 bytes] S: x OK Fetch completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8192 bytes] S: x OK Fetch completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [8193 bytes] [ _hangs until the server terminates the session for inactivity_ ] S: * BYE Disconnected for inactivity.
strace(1) show that Dovecot didn't send the response, even though the server log indicates that it's able to fully read the command.
Interestingly, when setting ‘imap_max_line_length’ to 4096, the server also hangs after receiving a command of size >4096 bytes (instead of replying with a tagged BAD response).
$ COMPRESS=y /tmp/many-fetch.pl 4096 C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4095 bytes] S: x OK Fetch completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4096 bytes] S: x OK Fetch completed (0.001 + 0.000 secs). C: x UID FETCH 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,… [4097 bytes] [ _hangs until the server terminates the session for inactivity_ ]
I'm also able to reproduce the buggy behavior against Dovecot versions found in other Debian releases. It's identical with 2.3.4 (Buster), the server also hang past 8192 bytes. 2.2.27 (Stretch) and 2.2.13 (Jessie) are able to send replies to 8k-long commands, but hang past 65536 bytes. For all 3 releases, without COMPRESS=DEFLATE Dovecot doesn't hang and rightfully sends tagged BAD responses to commands of size >65539 bytes.
So while the hanging behavior appears to be a long-standing bug, the fact that's it's now hit at min($imap_max_line_length, 8192) instead of $imap_max_line_length seems to be a regression from somewhere between 2.2.27 and 2.3.4.
I was able to confirm this problem with the current master. Tracking internally as DOP-1591.
Regards,
Stephan.
This bug is fixed now with https://github.com/dovecot/core/compare/14ab7acd036d5daab474d60919f69012f741...
Aki
participants (3)
-
Aki Tuomi
-
Guilhem Moulin
-
Stephan Bosch