diff options
Diffstat (limited to 'debian/patches/80_01-GnuTLS-fix-hanging-callout-connections.patch')
-rw-r--r-- | debian/patches/80_01-GnuTLS-fix-hanging-callout-connections.patch | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/debian/patches/80_01-GnuTLS-fix-hanging-callout-connections.patch b/debian/patches/80_01-GnuTLS-fix-hanging-callout-connections.patch new file mode 100644 index 0000000..0f36d73 --- /dev/null +++ b/debian/patches/80_01-GnuTLS-fix-hanging-callout-connections.patch @@ -0,0 +1,83 @@ +From 97c5e07c220b55d1c506a1798c9ce3ae3105adea Mon Sep 17 00:00:00 2001 +From: Jeremy Harris <jgh146exb@wizmail.org> +Date: Thu, 13 Feb 2020 16:45:38 +0000 +Subject: [PATCH 4/6] GnuTLS: fix hanging callout connections + +Broken-by: 925ac8e4f1 +(cherry picked from commit bd95ffc2ba87fbd3c752df17bc8fd9c01586d45a) +--- + doc/ChangeLog | 81 ++++--------------------------------------- + src/tls-gnu.c | 24 +++++++------ + 2 files changed, 20 insertions(+), 85 deletions(-) + +--- a/doc/ChangeLog ++++ b/doc/ChangeLog +@@ -67,6 +67,11 @@ JH/41 Bug 2571: Fix SPA authenticator. + being used. A malicious client could thus cause an out-of-bounds read and + possibly gain authentication. Fix by adding the check. + ++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 + ----------------- +--- a/src/tls-gnu.c ++++ b/src/tls-gnu.c +@@ -124,10 +124,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; +@@ -160,8 +167,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 = { +@@ -2790,9 +2795,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__, +@@ -2833,10 +2837,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 + |