Le 14/02/2018 à 18:53, Willy Tarreau a écrit :
On Wed, Feb 14, 2018 at 06:20:42PM +0100, Mateusz Malek wrote:
Hi,

On 14.02.2018 17:53, Willy Tarreau wrote:
On Wed, Feb 14, 2018 at 05:29:57PM +0100, Olivier Houchard wrote:
What about what's attached, instead ?
I think it should work. Mateusz, care to give it a try to confirm ?
If OK, I'll merge it.

I confirm, with this patch applied problem is gone.

Excellent, thanks for the quick test. Patch now applied.


Hi,

Someone on discourse reports a problem with this patch:


https://discourse.haproxy.org/t/random-sa-errors-with-haproxy-1-8-3/2116/6

I asked him to test the attached patch. But It could be cool to have more feedback on the fix. The bug can easily be reproduced by closing a connection opened with openssl s_client with a control-c.

Thanks
--
Christopher Faulet
>From e0ffb9cd3210ccc3eec96350b0405963746960d0 Mon Sep 17 00:00:00 2001
From: Christopher Faulet <cfau...@haproxy.com>
Date: Mon, 19 Feb 2018 14:25:15 +0100
Subject: [PATCH] BUG/MEDIUM: ssl: Shutdown the connection for reading on
 SSL_ERROR_SYSCALL

When SSL_read returns SSL_ERROR_SYSCALL and errno is unset or set to EAGAIN, the
connection must be shut down for reading. Else, the connection loops infinitly,
consuming all the CPU.

The bug was introduced in the commit 7e2e50500 ("BUG/MEDIUM: ssl: Don't always
treat SSL_ERROR_SYSCALL as unrecovarable."). This patch must be backported in
1.8 too.
---
 src/ssl_sock.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 93aec33c4..1cd1547c7 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -5449,10 +5449,9 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
 				break;
 			} else if (ret == SSL_ERROR_ZERO_RETURN)
 				goto read0;
-			/* For SSL_ERROR_SYSCALL, make sure the error is
-			 * unrecoverable before flagging the connection as
-			 * in error.
-			 */
+			/* For SSL_ERROR_SYSCALL, make sure to clear the error
+			 * stack before shutting down the connection for
+			 * reading. */
 			if (ret == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN))
 				goto clear_ssl_error;
 			/* otherwise it's a real error */
@@ -5465,16 +5464,19 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
 	conn_cond_update_sock_polling(conn);
 	return done;
 
+ clear_ssl_error:
+	/* Clear openssl global errors stack */
+	ssl_sock_dump_errors(conn);
+	ERR_clear_error();
  read0:
 	conn_sock_read0(conn);
 	goto leave;
+
  out_error:
 	conn->flags |= CO_FL_ERROR;
-clear_ssl_error:
 	/* Clear openssl global errors stack */
 	ssl_sock_dump_errors(conn);
 	ERR_clear_error();
-
 	goto leave;
 }
 
-- 
2.14.3

Reply via email to