On Wed, Aug 30, 2023 at 1:22 PM Rainer Jung <[email protected]> wrote:
>
> OpenSSL 3 flags some abortive shutdowns as an error different to what
> 1.1.1 did. This results in info log output in httpd:
>
> [Tue Aug 29 12:33:06.787210 2023] [ssl:info] [pid 1994673:tid 1994737]
> SSL Library Error: error:0A000126:SSL routines::unexpected eof while reading
> [Tue Aug 29 12:33:06.787374 2023] [ssl:info] [pid 1994673:tid 1994737]
> [client 1.2.3.4:54790] AH01998: Connection closed to child 215 with
> abortive shutdown (server myserver:443)
The info looks legit to me (someone closed the connection with no
close_notify), possibly we want to log it at APLOG_DEBUG/TRACEx still
if it happens too often?
We don't do that though for SSL_ERROR_ZERO_RETURN in openssl < 3, but
maybe we should too like in the attached patch (instead of r1912015)?
Regards;
Yann.
Index: modules/ssl/ssl_engine_io.c
===================================================================
--- modules/ssl/ssl_engine_io.c (revision 1911906)
+++ modules/ssl/ssl_engine_io.c (working copy)
@@ -721,6 +721,19 @@ static apr_status_t ssl_io_input_read(bio_filter_i
ssl_err = SSL_get_error(inctx->filter_ctx->pssl, rc);
c = (conn_rec*)SSL_get_app_data(inctx->filter_ctx->pssl);
+#ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING
+ if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_SSL &&
+ ERR_GET_REASON(ERR_peek_error()) == SSL_R_UNEXPECTED_EOF_WHILE_READING) {
+ ssl_err = SSL_ERROR_ZERO_RETURN;
+ }
+#endif
+ if (ssl_err == SSL_ERROR_ZERO_RETURN) {
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, inctx->rc, c,
+ "SSL input filter at EOF with no close_notify.");
+ inctx->rc = APR_EOF;
+ break;
+ }
+
if (ssl_err == SSL_ERROR_WANT_READ) {
/*
* If OpenSSL wants to read more, and we were nonblocking,
@@ -741,7 +754,8 @@ static apr_status_t ssl_io_input_read(bio_filter_i
}
continue; /* Blocking and nothing yet? Try again. */
}
- else if (ssl_err == SSL_ERROR_SYSCALL) {
+
+ if (ssl_err == SSL_ERROR_SYSCALL) {
if (APR_STATUS_IS_EAGAIN(inctx->rc)
|| APR_STATUS_IS_EINTR(inctx->rc)) {
/* Already read something, return APR_SUCCESS instead. */
@@ -763,10 +777,6 @@ static apr_status_t ssl_io_input_read(bio_filter_i
"SSL input filter read failed.");
}
}
- else if (rc == 0 && ssl_err == SSL_ERROR_ZERO_RETURN) {
- inctx->rc = APR_EOF;
- break;
- }
else /* if (ssl_err == SSL_ERROR_SSL) */ {
/*
* Log SSL errors and any unexpected conditions.
@@ -1413,17 +1423,8 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
apr_status_t rc = inctx->rc ? inctx->rc : outctx->rc ;
ssl_err = SSL_get_error(filter_ctx->pssl, n);
- if (ssl_err == SSL_ERROR_ZERO_RETURN) {
+ if (ssl_err == SSL_ERROR_WANT_READ) {
/*
- * The case where the connection was closed before any data
- * was transferred. That's not a real error and can occur
- * sporadically with some clients.
- */
- ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c, APLOGNO(02006)
- "SSL handshake stopped: connection was closed");
- }
- else if (ssl_err == SSL_ERROR_WANT_READ) {
- /*
* This is in addition to what was present earlier. It is
* borrowed from openssl_state_machine.c [mod_tls].
* TBD.
@@ -1431,8 +1432,9 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
outctx->rc = APR_EAGAIN;
return APR_EAGAIN;
}
- else if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_SSL &&
- ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) {
+
+ if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_SSL &&
+ ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) {
/*
* The case where OpenSSL has recognized a HTTP request:
* This means the client speaks plain HTTP on our HTTPS port.
@@ -1441,6 +1443,22 @@ static apr_status_t ssl_io_filter_handshake(ssl_fi
*/
return MODSSL_ERROR_HTTP_ON_HTTPS;
}
+
+#ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING
+ if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_SSL &&
+ ERR_GET_REASON(ERR_peek_error()) == SSL_R_UNEXPECTED_EOF_WHILE_READING) {
+ ssl_err = SSL_ERROR_ZERO_RETURN;
+ }
+#endif
+ if (ssl_err == SSL_ERROR_ZERO_RETURN) {
+ /*
+ * The case where the connection was closed before any data
+ * was transferred. That's not a real error and can occur
+ * sporadically with some clients.
+ */
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c, APLOGNO(02006)
+ "SSL handshake stopped: connection was closed");
+ }
else if (ssl_err == SSL_ERROR_SYSCALL) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rc, c, APLOGNO(02007)
"SSL handshake interrupted by system "