diff options
author | pgollucci <pgollucci@FreeBSD.org> | 2010-05-13 08:30:19 +0800 |
---|---|---|
committer | pgollucci <pgollucci@FreeBSD.org> | 2010-05-13 08:30:19 +0800 |
commit | f14f04522ecd883df5bca7f782e14cc174fe0047 (patch) | |
tree | c34c08aeb1b375a09bf51b97bfb101404bb9415a /www | |
parent | 8d4a58c5ecf31d32b41a82e19054ba6010f38053 (diff) | |
download | freebsd-ports-gnome-f14f04522ecd883df5bca7f782e14cc174fe0047.tar.gz freebsd-ports-gnome-f14f04522ecd883df5bca7f782e14cc174fe0047.tar.zst freebsd-ports-gnome-f14f04522ecd883df5bca7f782e14cc174fe0047.zip |
- Fix openssl rengotiation patch [1]
- Fix the openssl from ports flag
- Bump PORTREVISION
- Also patch 2 more CVEs
*) SECURITY: CVE-2010-0434 (cve.mitre.org)
Ensure each subrequest has a shallow copy of headers_in so that the
parent request headers are not corrupted. Elimiates a problematic
optimization in the case of no request body. PR 48359
[Jake Scott, William Rowe, Ruediger Pluem]
*) SECURITY: CVE-2008-2364 (cve.mitre.org)
mod_proxy_http: Better handling of excessive interim responses
from origin server to prevent potential denial of service and high
memory usage. Reported by Ryujiro Shibuya. [Ruediger Pluem,
Joe Orton, Jim Jagielski]
PR: ports/146389 [1]
Submitted by: several [1]
With Hat: apache@
Diffstat (limited to 'www')
-rw-r--r-- | www/apache20/Makefile | 4 | ||||
-rw-r--r-- | www/apache20/files/patch-CVE-2008-2364 | 62 | ||||
-rw-r--r-- | www/apache20/files/patch-CVE-2009-3555 | 340 | ||||
-rw-r--r-- | www/apache20/files/patch-CVE-2010-0434 | 11 |
4 files changed, 146 insertions, 271 deletions
diff --git a/www/apache20/Makefile b/www/apache20/Makefile index 0fc06a812d6c..5eb9d5285746 100644 --- a/www/apache20/Makefile +++ b/www/apache20/Makefile @@ -9,7 +9,7 @@ PORTNAME= apache PORTVERSION= 2.0.63 -PORTREVISION= 8 +PORTREVISION= 9 CATEGORIES= www MASTER_SITES= ${MASTER_SITE_APACHE_HTTPD} \ ${MASTER_SITE_LOCAL:S/$/:powerlogo/} @@ -147,7 +147,7 @@ CONFIGURE_ARGS+= --enable-ldap=shared --enable-auth-ldap --with-ldap \ .include "${APACHEDIR}/Makefile.modules" .include <bsd.port.pre.mk> -.if defined(OPENSSL_INSTALLED) +.if defined(WITH_OPENSSL_PORT) EXTRA_PATCHES+= ${FILESDIR}/extra-openssl-9.8up.patch .endif diff --git a/www/apache20/files/patch-CVE-2008-2364 b/www/apache20/files/patch-CVE-2008-2364 new file mode 100644 index 000000000000..4848ad92acb1 --- /dev/null +++ b/www/apache20/files/patch-CVE-2008-2364 @@ -0,0 +1,62 @@ +--- modules/proxy/proxy_http.c 2010/03/11 15:52:45 921907 ++++ modules/proxy/proxy_http.c 2010/03/11 15:54:18 921908 +@@ -1290,6 +1290,16 @@ + return 1; + } + ++/* ++ * Limit the number of interim respones we sent back to the client. Otherwise ++ * we suffer from a memory build up. Besides there is NO sense in sending back ++ * an unlimited number of interim responses to the client. Thus if we cross ++ * this limit send back a 502 (Bad Gateway). ++ */ ++#ifndef AP_MAX_INTERIM_RESPONSES ++#define AP_MAX_INTERIM_RESPONSES 10 ++#endif ++ + static + apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, + proxy_http_conn_t *p_conn, +@@ -1322,7 +1332,7 @@ + */ + rp->proxyreq = PROXYREQ_RESPONSE; + +- while (received_continue) { ++ while (received_continue && (received_continue <= AP_MAX_INTERIM_RESPONSES)) { + apr_brigade_cleanup(bb); + + len = ap_getline(buffer, sizeof(buffer), rp, 0); +@@ -1440,7 +1450,9 @@ + if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { + ap_set_content_type(r, apr_pstrdup(p, buf)); + } +- ap_proxy_pre_http_request(origin,rp); ++ if (!ap_is_HTTP_INFO(r->status)) { ++ ap_proxy_pre_http_request(origin, rp); ++ } + + /* handle Via header in response */ + if (conf->viaopt != via_off && conf->viaopt != via_block) { +@@ -1486,6 +1498,7 @@ + if ( r->status != HTTP_CONTINUE ) { + received_continue = 0; + } else { ++ received_continue++; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "proxy: HTTP: received 100 CONTINUE"); + } +@@ -1622,6 +1635,14 @@ + } + } + ++ /* See define of AP_MAX_INTERIM_RESPONSES for why */ ++ if (received_continue > AP_MAX_INTERIM_RESPONSES) { ++ return ap_proxyerror(r, HTTP_BAD_GATEWAY, ++ apr_psprintf(p, ++ "Too many (%d) interim responses from origin server", ++ received_continue)); ++ } ++ + if ( conf->error_override ) { + /* the code above this checks for 'OK' which is what the hook expects */ + if ( r->status == HTTP_OK ) diff --git a/www/apache20/files/patch-CVE-2009-3555 b/www/apache20/files/patch-CVE-2009-3555 index c6a7265b34f4..fd997ab960fc 100644 --- a/www/apache20/files/patch-CVE-2009-3555 +++ b/www/apache20/files/patch-CVE-2009-3555 @@ -1,279 +1,81 @@ -Modified patch from http://www.apache.org/dist/httpd/patches/apply_to_2.2.14/CVE-2009-3555-2.2.patch - ---- modules/ssl/mod_ssl.h.orig 2009-11-07 14:55:25.000000000 +0300 -+++ modules/ssl/mod_ssl.h 2009-11-07 14:56:40.000000000 +0300 -@@ -389,6 +389,19 @@ - int is_proxy; - int disabled; - int non_ssl_request; -+ -+ /* Track the handshake/renegotiation state for the connection so -+ * that all client-initiated renegotiations can be rejected, as a -+ * partial fix for CVE-2009-3555. */ -+ enum { -+ RENEG_INIT = 0, /* Before initial handshake */ -+ RENEG_REJECT, /* After initial handshake; any client-initiated -+ * renegotiation should be rejected */ -+ RENEG_ALLOW, /* A server-initated renegotiation is taking -+ * place (as dictated by configuration) */ -+ RENEG_ABORT /* Renegotiation initiated by client, abort the -+ * connection */ -+ } reneg_state; - } SSLConnRec; - - typedef struct { -@@ -585,7 +598,7 @@ - int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *); - SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); - void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); --void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int); -+void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE, int, int); - - /* Session Cache Support */ - void ssl_scache_init(server_rec *, apr_pool_t *); ---- modules/ssl/ssl_engine_init.c.orig 2009-11-07 14:57:31.000000000 +0300 -+++ modules/ssl/ssl_engine_init.c 2009-11-07 14:58:00.000000000 +0300 -@@ -464,10 +464,7 @@ - SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); - SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); - -- if (s->loglevel >= APLOG_DEBUG) { -- /* this callback only logs if LogLevel >= info */ -- SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState); -- } -+ SSL_CTX_set_info_callback(ctx, ssl_callback_Info); - } - - static void ssl_init_ctx_verify(server_rec *s, ---- modules/ssl/ssl_engine_io.c.orig 2009-11-07 14:58:35.000000000 +0300 -+++ modules/ssl/ssl_engine_io.c 2009-11-07 15:01:05.000000000 +0300 -@@ -102,6 +102,7 @@ - ap_filter_t *pInputFilter; - ap_filter_t *pOutputFilter; - int nobuffer; /* non-zero to prevent buffering */ -+ SSLConnRec *config; - } ssl_filter_ctx_t; - - typedef struct { -@@ -193,6 +194,12 @@ - { - bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); - -+ /* Abort early if the client has initiated a renegotiation. */ -+ if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) { -+ outctx->rc = APR_ECONNABORTED; -+ return -1; -+ } -+ - /* when handshaking we'll have a small number of bytes. - * max size SSL will pass us here is about 16k. - * (16413 bytes to be exact) -@@ -465,6 +472,12 @@ - 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. -@@ -1585,6 +1598,8 @@ - - filter_ctx = apr_palloc(c->pool, sizeof(ssl_filter_ctx_t)); - -+ filter_ctx->config = myConnConfig(c); -+ - filter_ctx->nobuffer = 0; - filter_ctx->pOutputFilter = ap_add_output_filter(ssl_io_filter, - filter_ctx, NULL, c); ---- modules/ssl/ssl_engine_kernel.c.orig 2009-11-07 15:01:41.000000000 +0300 -+++ modules/ssl/ssl_engine_kernel.c 2009-11-07 15:09:49.000000000 +0300 -@@ -611,6 +611,10 @@ - (unsigned char *)&id, - sizeof(id)); - -+ /* Toggle the renegotiation state to allow the new -+ * handshake to proceed. */ -+ sslconn->reneg_state = RENEG_ALLOW; -+ - SSL_renegotiate(ssl); - SSL_do_handshake(ssl); - -@@ -628,6 +632,8 @@ - SSL_set_state(ssl, SSL_ST_ACCEPT); - SSL_do_handshake(ssl); - -+ sslconn->reneg_state = RENEG_REJECT; -+ - if (SSL_get_state(ssl) != SSL_ST_OK) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, - "Re-negotiation handshake failed: " -@@ -1700,76 +1706,56 @@ - return; - } - --/* -- * This callback function is executed while OpenSSL processes the -- * SSL handshake and does SSL record layer stuff. We use it to -- * trace OpenSSL's processing in out SSL logfile. -- */ --void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) --{ -- conn_rec *c; -- server_rec *s; -- SSLSrvConfigRec *sc; -+/* Dump debugginfo trace to the log file. */ -+static void log_tracing_state(MODSSL_INFO_CB_ARG_TYPE ssl, conn_rec *c, -+ server_rec *s, int where, int rc) - -+{ - /* -- * find corresponding server -+ * create the various trace messages - */ -- if (!(c = (conn_rec *)SSL_get_app_data((SSL *)ssl))) { -- return; -+ if (where & SSL_CB_HANDSHAKE_START) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Handshake: start", SSL_LIBRARY_NAME); +Index: modules/ssl/ssl_engine_io.c +=================================================================== +--- modules/ssl/ssl_engine_io.c 2010-01-08 16:06:21.000000000 +0100 ++++ modules/ssl/ssl_engine_io.c 2010-01-08 15:31:05.000000000 +0100 +@@ -1241,9 +1241,17 @@ } -- -- s = c->base_server; -- if (!(sc = mySrvConfig(s))) { -- return; -+ else if (where & SSL_CB_HANDSHAKE_DONE) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Handshake: done", SSL_LIBRARY_NAME); - } -- -- /* -- * create the various trace messages -- */ -- if (s->loglevel >= APLOG_DEBUG) { -- if (where & SSL_CB_HANDSHAKE_START) { -- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -- "%s: Handshake: start", SSL_LIBRARY_NAME); -- } -- else if (where & SSL_CB_HANDSHAKE_DONE) { -- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -- "%s: Handshake: done", SSL_LIBRARY_NAME); -- } -- else if (where & SSL_CB_LOOP) { -- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -- "%s: Loop: %s", -- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -- } -- else if (where & SSL_CB_READ) { -+ else if (where & SSL_CB_LOOP) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Loop: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_READ) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Read: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_WRITE) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Write: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_ALERT) { -+ char *str = (where & SSL_CB_READ) ? "read" : "write"; -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Alert: %s:%s:%s", -+ SSL_LIBRARY_NAME, str, -+ SSL_alert_type_string_long(rc), -+ SSL_alert_desc_string_long(rc)); -+ } -+ else if (where & SSL_CB_EXIT) { -+ if (rc == 0) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -- "%s: Read: %s", -+ "%s: Exit: failed in %s", - SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); - } -- else if (where & SSL_CB_WRITE) { -+ else if (rc < 0) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -- "%s: Write: %s", -+ "%s: Exit: error in %s", - SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); - } -- else if (where & SSL_CB_ALERT) { -- char *str = (where & SSL_CB_READ) ? "read" : "write"; -- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -- "%s: Alert: %s:%s:%s", -- SSL_LIBRARY_NAME, str, -- SSL_alert_type_string_long(rc), -- SSL_alert_desc_string_long(rc)); -- } -- else if (where & SSL_CB_EXIT) { -- if (rc == 0) { -- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -- "%s: Exit: failed in %s", -- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -- } -- else if (rc < 0) { -- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -- "%s: Exit: error in %s", -- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -- } -- } + else { + /* We have no idea what you are talking about, so return an error. */ +- return APR_ENOTIMPL; ++ status = APR_ENOTIMPL; } - /* -@@ -1789,3 +1775,48 @@ ++ /* It is possible for mod_ssl's BIO to be used outside of the ++ * direct control of mod_ssl's input or output filter -- notably, ++ * when mod_ssl initiates a renegotiation. Switching the BIO mode ++ * back to "blocking" here ensures such operations don't fail with ++ * SSL_ERROR_WANT_READ. */ ++ inctx->block = APR_BLOCK_READ; ++ ++ /* Handle custom errors. */ + if (status != APR_SUCCESS) { + return ssl_io_filter_error(f, bb, status); } - } - -+/* -+ * This callback function is executed while OpenSSL processes the SSL -+ * handshake and does SSL record layer stuff. It's used to trap -+ * client-initiated renegotiations, and for dumping everything to the -+ * log. -+ */ -+void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) +Index: modules/ssl/ssl_engine_kernel.c +=================================================================== +--- modules/ssl/ssl_engine_kernel.c 2010-01-08 16:06:21.000000000 +0100 ++++ modules/ssl/ssl_engine_kernel.c 2010-01-08 15:24:48.000000000 +0100 +@@ -31,6 +31,29 @@ + #include "mod_ssl.h" + + static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); ++ ++/* Perform a speculative (and non-blocking) read from the connection ++ * filters for the given request, to determine whether there is any ++ * pending data to read. Return non-zero if there is, else zero. */ ++static int has_buffered_data(request_rec *r) +{ -+ conn_rec *c; -+ server_rec *s; -+ SSLConnRec *scr; ++ apr_bucket_brigade *bb; ++ apr_off_t len; ++ apr_status_t rv; ++ int result; + -+ /* Retrieve the conn_rec and the associated SSLConnRec. */ -+ if ((c = (conn_rec *)SSL_get_app_data((SSL *)ssl)) == NULL) { -+ return; -+ } ++ bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + -+ if ((scr = myConnConfig(c)) == NULL) { -+ return; -+ } ++ rv = ap_get_brigade(r->connection->input_filters, bb, AP_MODE_SPECULATIVE, ++ APR_NONBLOCK_READ, 1); ++ result = rv == APR_SUCCESS ++ && apr_brigade_length(bb, 1, &len) == APR_SUCCESS ++ && len > 0; + -+ /* If the reneg state is to reject renegotiations, check the SSL -+ * state machine and move to ABORT if a Client Hello is being -+ * read. */ -+ if ((where & SSL_CB_ACCEPT_LOOP) && scr->reneg_state == RENEG_REJECT) { -+ int state = SSL_get_state(ssl); ++ apr_brigade_destroy(bb); + -+ if (state == SSL3_ST_SR_CLNT_HELLO_A -+ || state == SSL23_ST_SR_CLNT_HELLO_A) { -+ scr->reneg_state = RENEG_ABORT; -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, -+ "rejecting client initiated renegotiation"); -+ } -+ } -+ /* If the first handshake is complete, change state to reject any -+ * subsequent client-initated renegotiation. */ -+ else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_INIT) { -+ scr->reneg_state = RENEG_REJECT; -+ } -+ -+ s = mySrvFromConn(c); -+ if (s && s->loglevel >= APLOG_DEBUG) { -+ log_tracing_state(ssl, c, s, where, rc); -+ } ++ return result; +} + + /* + * Post Read Request Handler +@@ -602,6 +625,23 @@ + else { + request_rec *id = r->main ? r->main : r; + ++ /* Additional mitigation for CVE-2009-3555: At this point, ++ * before renegotiating, an (entire) request has been read ++ * from the connection. An attacker may have sent further ++ * data to "prefix" any subsequent request by the victim's ++ * client after the renegotiation; this data may already ++ * have been read and buffered. Forcing a connection ++ * closure after the response ensures such data will be ++ * discarded. Legimately pipelined HTTP requests will be ++ * retried anyway with this approach. */ ++ if (has_buffered_data(r)) { ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, ++ "insecure SSL re-negotiation required, but " ++ "a pipelined request is present; keepalive " ++ "disabled"); ++ r->connection->keepalive = AP_CONN_CLOSE; ++ } ++ + /* do a full renegotiation */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Performing full renegotiation: " diff --git a/www/apache20/files/patch-CVE-2010-0434 b/www/apache20/files/patch-CVE-2010-0434 new file mode 100644 index 000000000000..0f6407d0e469 --- /dev/null +++ b/www/apache20/files/patch-CVE-2010-0434 @@ -0,0 +1,11 @@ +--- server/protocol.c 2010/03/11 15:55:59 921909 ++++ server/protocol.c 2010/03/11 15:57:26 921910 +@@ -1022,7 +1022,7 @@ + + rnew->status = HTTP_OK; + +- rnew->headers_in = r->headers_in; ++ rnew->headers_in = apr_table_copy(rnew->pool, r->headers_in); + rnew->subprocess_env = apr_table_copy(rnew->pool, r->subprocess_env); + rnew->headers_out = apr_table_make(rnew->pool, 5); + rnew->err_headers_out = apr_table_make(rnew->pool, 5); |