From: Daniel Ruggeri Date: Tue, 16 Oct 2018 20:24:23 +0000 (+0000) Subject: *) mod_ssl: Handle SSL_read() return code 0 similarly to <0. It is needed X-Git-Tag: 2.4.37~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e867202d41f23aaf2a837a5bef12f3620fb67788;p=thirdparty%2Fapache%2Fhttpd.git *) mod_ssl: Handle SSL_read() return code 0 similarly to <0. It is needed when using OpenSSL 1.1.1 and should not harm for versions before 1.1.1. Without the patch for 1.1.1 a 0 byte read no longer results in EAGAIN but instead in APR_EOF which leads to HTTP/2 failures. For the changelog: Fix HTTP/2 failures when using OpenSSL 1.1.1. trunk patch: http://svn.apache.org/r1843954 2.4.x patch: svn merge -c 1843954 ^/httpd/httpd/trunk . +1: rjung, druggeri, rpluem git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1844047 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/STATUS b/STATUS index a4fc0536b71..1878c4a66ef 100644 --- a/STATUS +++ b/STATUS @@ -125,18 +125,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - - *) mod_ssl: Handle SSL_read() return code 0 similarly to <0. It is needed - when using OpenSSL 1.1.1 and should not harm for versions before - 1.1.1. - Without the patch for 1.1.1 a 0 byte read no longer results in - EAGAIN but instead in APR_EOF which leads to HTTP/2 failures. - For the changelog: Fix HTTP/2 failures when using OpenSSL 1.1.1. - trunk patch: http://svn.apache.org/r1843954 - 2.4.x patch: svn merge -c 1843954 ^/httpd/httpd/trunk . - +1: rjung, druggeri, rpluem - -1: - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index d52d5e30caa..03aa0cec994 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -680,37 +680,36 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, } return inctx->rc; } - else if (rc == 0) { - /* If EAGAIN, we will loop given a blocking read, - * otherwise consider ourselves at EOF. - */ - if (APR_STATUS_IS_EAGAIN(inctx->rc) - || APR_STATUS_IS_EINTR(inctx->rc)) { - /* Already read something, return APR_SUCCESS instead. - * On win32 in particular, but perhaps on other kernels, - * a blocking call isn't 'always' blocking. + else /* (rc <= 0) */ { + int ssl_err; + conn_rec *c; + if (rc == 0) { + /* If EAGAIN, we will loop given a blocking read, + * otherwise consider ourselves at EOF. */ - if (*len > 0) { - inctx->rc = APR_SUCCESS; - break; - } - if (inctx->block == APR_NONBLOCK_READ) { - break; - } - } - else { - if (*len > 0) { - inctx->rc = APR_SUCCESS; + if (APR_STATUS_IS_EAGAIN(inctx->rc) + || APR_STATUS_IS_EINTR(inctx->rc)) { + /* Already read something, return APR_SUCCESS instead. + * On win32 in particular, but perhaps on other kernels, + * a blocking call isn't 'always' blocking. + */ + if (*len > 0) { + inctx->rc = APR_SUCCESS; + break; + } + if (inctx->block == APR_NONBLOCK_READ) { + break; + } } else { - inctx->rc = APR_EOF; + if (*len > 0) { + inctx->rc = APR_SUCCESS; + break; + } } - break; } - } - else /* (rc < 0) */ { - int ssl_err = SSL_get_error(inctx->filter_ctx->pssl, rc); - conn_rec *c = (conn_rec*)SSL_get_app_data(inctx->filter_ctx->pssl); + ssl_err = SSL_get_error(inctx->filter_ctx->pssl, rc); + c = (conn_rec*)SSL_get_app_data(inctx->filter_ctx->pssl); if (ssl_err == SSL_ERROR_WANT_READ) { /* @@ -754,6 +753,10 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, "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. @@ -763,6 +766,10 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, mySrvFromConn(c)); } + if (rc == 0) { + inctx->rc = APR_EOF; + break; + } if (inctx->rc == APR_SUCCESS) { inctx->rc = APR_EGENERAL; }