From 3e7f4235d8f86a406a9fc7a8f7d4d09a0516d7ed Mon Sep 17 00:00:00 2001
From: Fabian Keil <fk@fabiankeil.de>
Date: Tue, 22 Sep 2020 13:09:41 +0200
Subject: [PATCH] close_client_ssl_connection(): Set SSL_RECEIVED_SHUTDOWN
... so the BIO_free_all() call later on does not result
in OpenSSL waiting for a shutdown alert.
Prevents temporary hangs like this:
(gdb) where
#0 0x0000000801d1f8da in _read () from /lib/libc.so.7
#1 0x00000008019aebe6 in __thr_read (fd=26, buf=0x804a2e8c3, nbytes=5) at /usr/src/lib/libthr/thread/thr_syscalls.c:418
#2 0x0000000800cafb62 in sock_read (b=0x80895ffb0, out=0x804a2e8c3 "\027\003\003\004\a", outl=5) at /usr/src/crypto/openssl/crypto/bio/bss_sock.c:140
#3 0x0000000800db9f34 in BIO_read (b=0x80895ffb0, out=0x804a2e8c3, outl=5) at /usr/src/crypto/openssl/crypto/bio/bio_lib.c:210
#4 0x000000080176a80d in ssl3_read_n (s=0x806371a80, n=5, max=5, extend=<optimized out>) at /usr/src/crypto/openssl/ssl/s3_pkt.c:258
#5 0x000000080176b87c in ssl3_get_record (s=0x806371a80) at /usr/src/crypto/openssl/ssl/s3_pkt.c:342
#6 ssl3_read_bytes (s=<optimized out>, type=<optimized out>, buf=<optimized out>, len=<optimized out>, peek=0) at /usr/src/crypto/openssl/ssl/s3_pkt.c:1233
#7 0x000000080176e7bb in ssl3_shutdown (s=0x806371a80) at /usr/src/crypto/openssl/ssl/s3_lib.c:4396
#8 0x00000008017505b0 in ssl_free (a=0x80895fed0) at /usr/src/crypto/openssl/ssl/bio_ssl.c:126
#9 0x0000000800dbab7e in BIO_free (a=0x80895fed0) at /usr/src/crypto/openssl/crypto/bio/bio_lib.c:133
#10 BIO_free_all (bio=0x0) at /usr/src/crypto/openssl/crypto/bio/bio_lib.c:509
#11 0x000000000045b301 in free_client_ssl_structures (csp=0x807678a88) at openssl.c:907
#12 0x000000000045b391 in close_client_ssl_connection (csp=0x807678a88) at openssl.c:883
#13 0x0000000000438603 in serve (csp=0x807678a88) at jcc.c:4516
#14 0x00000008019ac08c in thread_start (curthread=0x807744200) at /usr/src/lib/libthr/thread/thr_create.c:290
#15 0x0000000000000000 in ?? ()
---
openssl.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/openssl.c b/openssl.c
index 28783bed..3c264f16 100644
--- a/openssl.c
+++ b/openssl.c
@@ -870,6 +870,7 @@ exit:
extern void close_client_ssl_connection(struct client_state *csp)
{
struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
+ SSL *ssl;
if (csp->ssl_with_client_is_opened == 0)
{
@@ -880,6 +881,20 @@ extern void close_client_ssl_connection(struct client_state *csp)
* Notifying the peer that the connection is being closed.
*/
BIO_ssl_shutdown(ssl_attr->openssl_attr.bio);
+ if (BIO_get_ssl(ssl_attr->openssl_attr.bio, &ssl) != 1)
+ {
+ log_ssl_errors(LOG_LEVEL_ERROR,
+ "BIO_get_ssl() failed in close_client_ssl_connection()");
+ }
+ else
+ {
+ /*
+ * Pretend we received a shutdown alert so
+ * the BIO_free_all() call later on returns
+ * quickly.
+ */
+ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+ }
free_client_ssl_structures(csp);
csp->ssl_with_client_is_opened = 0;
}
--
2.50.1