]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: ssl: Don't always treat SSL_ERROR_SYSCALL as unrecovarable.
authorOlivier Houchard <ohouchard@haproxy.com>
Tue, 13 Feb 2018 14:17:23 +0000 (15:17 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 14 Feb 2018 17:44:28 +0000 (18:44 +0100)
Bart Geesink reported some random errors appearing under the form of
termination flags SD in the logs for connections involving SSL traffic
to reach the servers.

Tomek Gacek and Mateusz Malek finally narrowed down the problem to commit
c2aae74 ("MEDIUM: ssl: Handle early data with OpenSSL 1.1.1"). It happens
that the special case of SSL_ERROR_SYSCALL isn't handled anymore since
this commit.

SSL_read() might return <= 0, and SSL_get_erro() return SSL_ERROR_SYSCALL,
without meaning the connection is gone. Before flagging the connection
as in error, check the errno value.

This should be backported to 1.8.

src/ssl_sock.c

index aee3cd9655ba3d47fa260153c90b6c5b091a0323..e6945c0c2315195aa76532990945f2cc3da5083c 100644 (file)
@@ -5434,6 +5434,12 @@ 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.
+                        */
+                       if (ret == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN))
+                               goto clear_ssl_error;
                        /* otherwise it's a real error */
                        goto out_error;
                }
@@ -5448,11 +5454,12 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
        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();
 
-       conn->flags |= CO_FL_ERROR;
        goto leave;
 }