From: Graham Leggett Date: Mon, 1 Mar 2010 01:31:36 +0000 (+0000) Subject: mod_ssl: Fix potential SSL I/O filter hang if a long list of X-Git-Tag: 2.2.15~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40b00fabe1597f21e591c9bb0567be743e080174;p=thirdparty%2Fapache%2Fhttpd.git mod_ssl: Fix potential SSL I/O filter hang if a long list of trusted CAs is configured for client cert auth. PR 46952 +1: jorton, wrowe [from review of svn patch], minfrin git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@917343 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 6ffa7215d69..dd12f1afa4d 100644 --- a/CHANGES +++ b/CHANGES @@ -42,6 +42,9 @@ Changes with Apache 2.2.15 allows insecure renegotiation with clients which do not yet support the secure renegotiation protocol. [Joe Orton] + *) mod_ssl: Fix a potential I/O hang if a long list of trusted CAs + is configured for client cert auth. PR 46952. [Joe Orton] + *) core: Fix potential memory leaks by making sure to not destroy bucket brigades that have been created by earlier filters. [Stefan Fritsch] diff --git a/STATUS b/STATUS index 2500926a488..fe90d21ac6a 100644 --- a/STATUS +++ b/STATUS @@ -99,14 +99,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_ssl: Fix potential SSL I/O filter hang if a long list of - trusted CAs is configured for client cert auth. PR 46952 - Trunk version of patch: - http://svn.apache.org/viewcvs.cgi?rev=788715&view=rev - Backport version for 2.2.x of patch: - http://people.apache.org/~jorton/ms_flush.diff - +1: jorton, wrowe [from review of svn patch], minfrin - 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 72536702269..2ddaa920811 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -465,7 +465,6 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen) apr_size_t inl = inlen; bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)(bio->ptr); apr_read_type_e block = inctx->block; - SSLConnRec *sslconn = myConnConfig(inctx->f->c); inctx->rc = APR_SUCCESS; @@ -473,23 +472,19 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen) if (!in) return 0; - /* Abort early if the client has initiated a renegotiation. */ - if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) { - inctx->rc = APR_ECONNABORTED; - return -1; - } - - /* XXX: flush here only required for SSLv2; - * OpenSSL calls BIO_flush() at the appropriate times for - * the other protocols. + /* In theory, OpenSSL should flush as necessary, but it is known + * not to do so correctly in some cases; see PR 46952. + * + * Historically, this flush call was performed only for an SSLv2 + * connection or for a proxy connection. Calling _out_flush + * should be very cheap in cases where it is unnecessary (and no + * output is buffered) so the performance impact of doing it + * unconditionally should be minimal. */ - if ((SSL_version(inctx->ssl) == SSL2_VERSION) || sslconn->is_proxy) { - if (bio_filter_out_flush(inctx->bio_out) < 0) { - bio_filter_out_ctx_t *outctx = - (bio_filter_out_ctx_t *)(inctx->bio_out->ptr); - inctx->rc = outctx->rc; - return -1; - } + if (bio_filter_out_flush(inctx->bio_out) < 0) { + bio_filter_out_ctx_t *outctx = inctx->bio_out->ptr; + inctx->rc = outctx->rc; + return -1; } BIO_clear_retry_flags(bio);