GnuTLS: fix hanging callout connections
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 13 Feb 2020 16:45:38 +0000 (16:45 +0000)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Sat, 26 Sep 2020 16:32:44 +0000 (18:32 +0200)
Broken-by: 925ac8e4f1
(cherry picked from commit bd95ffc2ba87fbd3c752df17bc8fd9c01586d45a)

doc/doc-txt/ChangeLog
src/src/tls-gnu.c

index a5b58f78130ad4ef852d8b95373bb6f58c4be290..b782352533dc66672a7594f0fe5e0d17258967c2 100644 (file)
@@ -5,82 +5,13 @@ affect Exim's operation, with an unchanged configuration file.  For new
 options, and new features, see the NewStuff file next to this ChangeLog.
 
 
-Since version 4.92
-------------------
+Backported Exim version 4.94 (this list is imcomplete)
+------------------------------------------------------
 
-JH/06 Fix buggy handling of autoreply bounce_return_size_limit, and a possible
-      buffer overrun for (non-chunking) other transports.
-
-JH/07 GnuTLS: Our use of late (post-handshake) certificate verification, under
-      TLS1.3, means that a server rejecting a client certificate is not visible
-      to the client until the first read of encrypted data (typically the
-      response to EHLO).  Add detection for that case and treat it as a failed
-      TLS connection attempt, so that the normal retry-in-clear can work (if
-      suitably configured).
-
-JB/01 Bug 2375: fix expansions of 822 addresses having comments in local-part
-      and/or domain.  Found and fixed by Jason Betts.
-
-JH/08 Add hardening against SRV & TLSA lookups the hit CNAMEs (a nonvalid
-      configuration).  If a CNAME target was not a wellformed name pattern, a
-      crash could result.
-
-JH/09 Logging: Fix initial listening-on line for multiple ports for an IP when
-      the OS reports them interleaved with other addresses.
-
-JH/10 OpenSSL: Fix aggregation of messages.  Previously, when PIPELINING was
-      used both for input and for a verify callout, both encrypted, SMTP
-      responses being sent by the server could be lost.  This resulted in
-      dropped connections and sometimes bounces generated by a peer sending
-      to this system.
-
-JH/11 Harden plaintext authenticator against a badly misconfigured client-send
-      string.  Previously it was possible to cause undefined behaviour in a
-      library routine (usually a crash).  Found by "zerons".
-
-JH/12 Bug 2384: fix "-bP smtp_receive_timeout".  Previously it returned no
-      output.
-
-JH/13 Bug 2386: Fix builds with Dane under LibreSSL 2.9.0 onward.  Some old
-      API was removed, so update to use the newer ones.
-
-
-JH/16 GnuTLS: rework ciphersuite strings under recent library versions.  Thanks
-      to changes apparently associated with TLS1.3 handling some of the APIs
-      previously used were either nonfunctional or inappropriate.  Strings
-      like TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM__AEAD:256
-      and TLS1.2:ECDHE_SECP256R1__RSA_SHA256__AES_128_CBC__SHA256:128 replace
-      the previous TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256 .
-      This affects log line X= elements, the $tls_{in,out}_cipher variables,
-      and the use of specific cipher names in the encrypted= ACL condition.
-
-JH/18 GnuTLS: fix $tls_out_ocsp under hosts_request_ocsp. Previously the
-      verification result was not updated unless hosts_require_ocsp applied.
-
-JH/19 Bug 2398: fix listing of a named-queue.  Previously, even with the option
-      queue_list_requires_admin set to false, non-admin users were denied the
-      facility.
-
-JH/20 Bug 2389: fix server advertising of usable certificates, under GnuTLS in
-      directory-of-certs mode.  Previously they were advertised despite the
-      documentation.
-
-JH/27 Bug 2404: Use the main-section configuration option "dsn_from" for
-      success-DSN messages.  Previously the From: header was always the default
-      one for these; the option was ignored.
-
-PP/01 Unbreak heimdal_gssapi, broken in 4.92.
-
-JH/29 Fix DSN Final-Recipient: field.  Previously it was the post-routing
-      delivery address, which leaked information of the results of local
-      forwarding.  Change to the original envelope recipient address, per
-      standards.
-
-JH/30 Bug 2411: Fix DSN generation when RFC 3461 failure notification is
-      requested.  Previously not bounce was generated and a log entry of
-      error ignored was made.
-
-JH/31 Avoid re-expansion in ${sort } expansion. (CVE-2019-13917, OVE-20190718-0006)
+JH/25 Fix use of concurrent TLS connections under GnuTLS.  When a callout was
+      done during a receiving connection, and both used TLS, global info was
+      used rather than per-connection info for tracking the state of data
+      queued for transmission.  This could result in a connection hang.
 
 
 Exim version 4.92
index 867dbbe3dd8a438bcb1a951011068c39ab30e8d3..822ad89c6d43e88656b28079f1af23b1ffc76cc3 100644 (file)
@@ -127,10 +127,17 @@ typedef struct exim_gnutls_state {
   enum peer_verify_requirement verify_requirement;
   int                  fd_in;
   int                  fd_out;
-  BOOL                 peer_cert_verified;
-  BOOL                 peer_dane_verified;
-  BOOL                 trigger_sni_changes;
-  BOOL                 have_set_peerdn;
+
+  BOOL                 peer_cert_verified:1;
+  BOOL                 peer_dane_verified:1;
+  BOOL                 trigger_sni_changes:1;
+  BOOL                 have_set_peerdn:1;
+  BOOL                 xfer_eof:1;     /*XXX never gets set! */
+  BOOL                 xfer_error:1;
+#ifdef SUPPORT_CORK
+  BOOL                 corked:1;
+#endif
+
   const struct host_item *host;                /* NULL if server */
   gnutls_x509_crt_t    peercert;
   uschar               *peerdn;
@@ -163,8 +170,6 @@ typedef struct exim_gnutls_state {
   uschar *xfer_buffer;
   int xfer_buffer_lwm;
   int xfer_buffer_hwm;
-  BOOL xfer_eof;       /*XXX never gets set! */
-  BOOL xfer_error;
 } exim_gnutls_state_st;
 
 static const exim_gnutls_state_st exim_gnutls_state_init = {
@@ -2831,9 +2836,8 @@ ssize_t outbytes;
 size_t left = len;
 exim_gnutls_state_st * state = ct_ctx ? ct_ctx : &state_server;
 #ifdef SUPPORT_CORK
-static BOOL corked = FALSE;
 
-if (more && !corked) gnutls_record_cork(state->session);
+if (more && !state->corked) gnutls_record_cork(state->session);
 #endif
 
 DEBUG(D_tls) debug_printf("%s(%p, " SIZE_T_FMT "%s)\n", __FUNCTION__,
@@ -2874,10 +2878,10 @@ if (len > INT_MAX)
   }
 
 #ifdef SUPPORT_CORK
-if (more != corked)
+if (more != state->corked)
   {
   if (!more) (void) gnutls_record_uncork(state->session, 0);
-  corked = more;
+  state->corked = more;
   }
 #endif